程序流程:
从数据库中把数据分页查询出来.
再把数据用dom4j组成xml.
最后转成byte数组用socket发送.如果数据库中数据有二进制数据的话.byte数组则会很大.这里用base64编码.比原来的还要大些.而且是多线程的频繁操作.
程序跑了一会就Game Over了. OutOfMemoryError 不知道有什么好办法来解决这个问题?我想到的是一个是加大VM的内存设置.但这个总是不能解决根本办法吧.
java程序内存好象只增不减.而且对于一下要开辟大内存的byte数组很容易就挂了.先谢过..
从数据库中把数据分页查询出来.
再把数据用dom4j组成xml.
最后转成byte数组用socket发送.如果数据库中数据有二进制数据的话.byte数组则会很大.这里用base64编码.比原来的还要大些.而且是多线程的频繁操作.
程序跑了一会就Game Over了. OutOfMemoryError 不知道有什么好办法来解决这个问题?我想到的是一个是加大VM的内存设置.但这个总是不能解决根本办法吧.
java程序内存好象只增不减.而且对于一下要开辟大内存的byte数组很容易就挂了.先谢过..
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Iterator;
import java.util.Set;public class NioEchoServer { private static Selector roller = null; private static final int port = 5000; private static NioEchoServer instance = null; private ThreadLocal<StringBuffer> stringLocal = new ThreadLocal<StringBuffer>(); private NioEchoServer() throws IOException {
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.socket().bind(new InetSocketAddress(port));
serverChannel.configureBlocking(false);
serverChannel.register(roller, SelectionKey.OP_ACCEPT);
} public synchronized static NioEchoServer getInstance() throws IOException {
if (instance == null) {
roller = Selector.open();
instance = new NioEchoServer();
}
return instance;
} public void start() throws IOException {
int keyAdded = 0;
while ((keyAdded = roller.select()) > 0) {
Set<SelectionKey> keySets = roller.selectedKeys();
Iterator iter = keySets.iterator();
while (iter.hasNext()) {
SelectionKey key = (SelectionKey) iter.next();
iter.remove();
actionHandler(key);
}
}
} public void actionHandler(SelectionKey key) throws IOException {
if (key.isAcceptable()) {
ServerSocketChannel serverChannel = (ServerSocketChannel) key
.channel();
SocketChannel socketChannel = serverChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(roller, SelectionKey.OP_READ);
} else if (key.isReadable()) {
ByteBuffer buffer = ByteBuffer.allocate(16);
SocketChannel socketChannel = (SocketChannel) key.channel();
socketChannel.read(buffer);
buffer.flip();
String temp = decode(buffer);
StringBuffer strBuffer = stringLocal.get();
if (strBuffer == null) {
strBuffer = new StringBuffer();
} strBuffer.append(temp); //if (temp.equals("\r\n")) {
System.out.println(strBuffer.toString());
strBuffer = null;
//}
stringLocal.set(strBuffer);
}
} public String decode(ByteBuffer buffer) {
Charset charset = null;
CharsetDecoder decoder = null;
CharBuffer charBuffer = null;
try {
charset = Charset.forName("UTF-8");
decoder = charset.newDecoder();
charBuffer = decoder.decode(buffer);
return charBuffer.toString();
} catch (Exception ex) {
ex.printStackTrace();
return "";
}
} public static void main(String[] args) {
try {
NioEchoServer.getInstance().start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package NioTest;import java.io.IOException;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;public class Client { private static final String EXIT = "EXIT"; private InetAddress host;
private int port; public Client(InetAddress host, int port) {
this.host = host;
this.port = port;
} public void startClient() throws IOException {
// 创建SocketChannel
SocketChannel channel = SocketChannel.open(new InetSocketAddress(host,
port));
channel.configureBlocking(false); // 创建Selector
Selector selector = Selector.open();
// 向Selector注册我们需要的READ事件
SelectionKey skey = channel.register(selector, SelectionKey.OP_WRITE);
boolean stop = false;
int n = 0;
int read = 0;
ByteBuffer buffer = ByteBuffer.allocate(1024); System.out.println("Client Start"); // 轮询
while (!stop) {
// 获取Selector返回的时间值
n = selector.select(); // 当传回的值大于0事,读时间发生了
if (n > 0) {
Set set = selector.selectedKeys();
Iterator it = set.iterator(); while (it.hasNext()) {
skey = (SelectionKey) it.next();
it.remove(); if (skey.isReadable()) {
SocketChannel sc = (SocketChannel) skey.channel(); while ((read = sc.read(buffer)) != -1) {
if (read == 0)
break;
buffer.flip();
byte[] array = new byte[read];
buffer.get(array);
String s = new String(array);
System.out.print(s);
buffer.clear(); if (s.endsWith(EXIT)) {
stop = true;
System.out.println();
}
}
}
}
}
} channel.close();
System.out.println("Client Stop");
} public static void main(String[] args) throws Exception {
Client client = new Client(InetAddress.getLocalHost(), 5000);
client.startClient();
}
private ByteBuffer sendBuffer = ByteBuffer.allocate(1024);
}
2. dom4j本身解析耗用的内存就比较大,大概是1:10
3. 把虚拟机内存改大一些:-Xms512m -Xmx1024m
先把附件之前的文本输出,然后把文件读一点,编码一点,输出一点,然后再把后面的文档输出.这问题本身和NIO没有任何关系.因为它是内存中存储不了大的数据,不知道为什么要有扯到NIO.
<xml>
<otherfiled>value</otherfiled>
<binfile></binfile>
<otherfiled></otherfiled>输出<xml>
<otherfiled>value</otherfiled>
<binfile>
然后数据库中的二进制对象,从inputStream每读byte[59],编码,输出,完成后再输出></binfile>
<otherfiled></otherfiled>
这样有处理10M内存就足够了.以前486上一般有8M内存就不错了,处理几百兆的文件还不是一样.
关于socket方面.我这是建的长连接.每3M为分包点发一个包.
我觉的问题关键不在这能否不用base64编码..老板要求xml格式必须符合soap格式.本来想用MIME附件形式的.但还是没有被通过.关于建个缓冲的byte流的办法我也想过.但不是很好做.可能我技术还没达到.
程序要求是把数据库里的数据组成xml包以socket发送.
从blob中读取用一点一点的读.但最终还是要以dom树的形式放到内存中!
接着把dom树转成byte数组.一个具大的byte数组.10M左右.
总不能xml组一半发一次.再组一半发一次吧.
而且还是多线程并发处理.不知道如何是好.byte[] btRet = null;
btRet = document.asXML().getBytes();
byte[] rt = new byte[9];假如它编码后的Base64字符串为: Xyzf65D9xcvf
你从数据库读到blob后先不要把blob编码进去,直接用rt这个byte代替,放到dom树中,最后dom树生成后,
得到一个XML文本,然后找到Xyzf65D9xcvf前的内容先输出去,再读blob编一点输出一点,再把Xyzf65D9xcvf后的内容输出去.
如果觉得生成dom树时,如果不读blog,数据库连结太久,就先把它读到一个临时文件中,dom树生成后再从这个临时文件中读取.这手多线程没有任何关系.