我正在将图像字节写入ByteArrayOutputStream
,然后通过套接字发送它。
问题是,当我这样做时
ImageIO.write(image, "gif", byteArray);
内存非常多,有点内存泄漏。
我使用此
发送ImageIO.write(image, "gif", byteArrayO);
byte [] byteArray = byteArrayO.toByteArray();
byteArrayO.flush();
byteArrayO.reset();
Connection.pw.println("" + byteArray.length);
int old = Connection.client.getSendBufferSize();
Connection.client.setSendBufferSize(byteArray.length);
Connection.client.getOutputStream().write(byteArray, 0, byteArray.length);
Connection.client.getOutputStream().flush();
image.flush();
image = null;
byteArrayO = null;
byteArray = null;
System.gc();
Connection.client.setSendBufferSize(old);
正如您所看到的,我已经尝试过所有方法,当我写入ByteArrayOutputStream
时,错误就出现了,而不是在我转移它时。接收方没有任何错误。
任何方法我都可以清除byteArray,并从内存中删除它中的所有内容?我知道reset()
有,但它不在这里。我想在完成后直接处理ByteArrayOutputStream
。
答案 0 :(得分:4)
为什么你必须摆弄发送缓冲区大小?你在这个套接字上使用什么样的协议?它应该就像:
一样简单ImageIO.write(image, "gif", Connection.client.getOutputStream());
如果必须使用ByteArrayOutputStream
,请至少使用
byteArrayO.writeTo(Connection.client.getOutputStream())
所以你不要多余byte[]
。
答案 1 :(得分:4)
@ChristofferHammarström可能有最好的解决方案,但我会添加它来尝试解释内存使用情况。
这2行创建了3个图像数据副本:
ImageIO.write(image, "gif", byteArrayO);
byte [] byteArray = byteArrayO.toByteArray();
执行此操作后,您将拥有一个存储在image中的数据副本,一个副本位于ByteArrayOutputStream中,另一个副本位于字节数组中(toByteArray()不返回它创建副本的内部缓冲区。)
调用reset()不释放ByteArrayOutputStream中的内存,它只是将位置计数器重置为0.数据仍在那里。
要允许先前释放内存,您可以在完成后立即将每个项目指定为null。这将允许垃圾收集器收集内存,如果它决定先运行。 EG:
ImageIO.write(image, "gif", byteArrayO);
image = null;
byte [] byteArray = byteArrayO.toByteArray();
byteArrayO = null;
...
答案 2 :(得分:1)
这不是你想要的答案,而是你可能想要考虑的事情。
为什么不创建一个字节数组池,并在每次需要时重新使用它们。这样会更有效率,因为您不会一直创建新阵列并将它们丢弃。使用较少的gc总是一件好事。您还可以保证应用程序有足够的内存来运行。
答案 3 :(得分:0)
您可以请求VM通过System.gc()
运行垃圾回收,但不保证实际发生。虚拟机在确定有必要或适当的时候执行垃圾收集。
答案 4 :(得分:0)
你所描述的是很正常的。它必须将您正在创建的图像的字节放在某处。
您可以使用FileOutputStream将字节写入,而不是内存。然后,您必须创建一个FileInputStream来从您写入的文件中读取一个循环,该循环将字节读入一个64k大小的字节数组缓冲区,然后将这些字节写入连接的输出流。
你提到错误。如果您收到错误,那么错误是什么?
如果使用客户端JVM(java的-client参数),则可能会将内存返回给操作系统,Java进程将再次收缩。我不确定这一点。
如果您不喜欢JAI使用多少内存,可以尝试使用Sanselan:http://commons.apache.org/imaging/