我正在使用像这样的ByteArrayOutputStreams通过套接字发送图像。
ImageIO.write(image, "gif", byteArrayO);
byte [] byteArray = byteArrayO.toByteArray();
Connection.pw.println("" + byteArray.length);
int old = Connection.client.getSendBufferSize();
Connection.client.setSendBufferSize(byteArray.length);
Connection.client.getOutputStream().write(byteArray, 0, byteArray.length);
一切正常,图像最终是130kb,我就像这样接收
int nbrToRead = Integer.parseInt(slave.input.readLine().trim());
int old = slave.socket.getReceiveBufferSize();
slave.socket.setReceiveBufferSize(nbrToRead);
byte[] byteArray = new byte[nbrToRead];
int nbrRd = 0;
int nbrLeftToRead = nbrToRead;
while (nbrLeftToRead > 0) {
int rd = slave.socket.getInputStream().read(byteArray, nbrRd, nbrLeftToRead);
if (rd < 0)
break;
nbrRd += rd;
nbrLeftToRead -= rd;
}
ByteArrayInputStream byteArrayI = new ByteArrayInputStream(byteArray);
BufferedImage img = ImageIO.read(byteArrayI);
它运行良好,但每个发送java内存堆的图像增加了50 MB。我已经尝试过设置receivebuffersize,但它仍然保持不变。它在堆中达到最大值,然后停留一段时间然后停止。
如何清除缓冲区,以便在收到字节时它会处理它们?
答案 0 :(得分:1)
有些事情让人想起:
答案 1 :(得分:0)
确保您的对象在发送后被取消引用,因为剩余的引用会将您的图像保留在内存中。您可以通过将该对象的所有实例设置为null
来完成此操作。
此外,完成后调用flush()
和close()
可以极大地帮助您的内存使用。
我希望这有帮助!
答案 2 :(得分:0)
您没有向我们展示您的所有方法,但在等待下一张图像时,您可能在范围内有大内存局部变量。
试试这个:
// after you've finished with the input, dereference the memory-heavy objects...
byteArray = null;
byteArrayI = null;
此外,您可以通过调用System.gc()
并生成线程,将JVM“轻推”到垃圾收集(您无法使垃圾收集)。如果单独归零不起作用,请尝试添加此
System.gc(); // "suggest" garbage collection to execute
Thread.yield(); // I have seen this encourage garbage collection to execute
答案 3 :(得分:0)
我愿意打赌Connection
拥有ObjectOutputStream
。如果这是真的,那么您需要在该流上调用reset()
。
答案 4 :(得分:0)
我评论过,但也把它作为答案。
当您创建内存中BufferedImage
时,必须在完成内容后调用flush()
。
我非常怀疑你的内存泄漏是从那里来的。
而且,正如Malached所说,确保所有内容(BufferedImages,I / O引用等)都不会留下gc
为他们工作的任何类型的引用。
System.gc()
不是解决方案,如果情况不是您的物理内存确实小于memory-leak-free
程序,那么您必须在gc
自己工作之前尝试。< / p>