Wil*_*röm 3 java sockets memory-leaks bytearrayoutputstream
我正在写入图像字节,ByteArrayOutputStream然后通过套接字发送它。问题是,当我这样做
ImageIO.write(image, "gif", byteArray);
Run Code Online (Sandbox Code Playgroud)
内存上升很多,有点内存泄漏。
我用这个发送
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);
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我已经尝试了所有方法,错误是在我写入 时出现ByteArrayOutputStream,而不是在我传输时出现。接收器没有得到任何错误。
有什么办法可以清除byteArray,并从内存中删除它的所有内容?我知道reset()有,但这里没有。完成后,我想ByteArrayOutputStream直接处理。
为什么你必须摆弄发送缓冲区的大小?你在这个套接字之上使用什么样的协议?它应该很简单:
ImageIO.write(image, "gif", Connection.client.getOutputStream());
Run Code Online (Sandbox Code Playgroud)
如果您必须使用 a ByteArrayOutputStream,至少使用
byteArrayO.writeTo(Connection.client.getOutputStream())
Run Code Online (Sandbox Code Playgroud)
所以你不会做额外的冗余byte[]。
@Christoffer Hammarström 可能有最好的解决方案,但我会添加这个来解释内存使用情况。
这 2 行正在创建图像数据的 3 个副本:
ImageIO.write(image, "gif", byteArrayO);
byte [] byteArray = byteArrayO.toByteArray();
Run Code Online (Sandbox Code Playgroud)
执行此操作后,您将有一份存储在图像中的数据副本,一份在 ByteArrayOutputStream 中,另一份在字节数组中(toByteArray() 不返回它创建副本的内部缓冲区)。
调用 reset() 不会释放 ByteArrayOutputStream 内的内存,它只是将位置计数器重置为 0。数据仍然存在。
为了让内存更早释放,您可以在完成每个项目后立即将其分配为 null。如果垃圾收集器决定更早运行,这将允许内存被垃圾收集器收集。例如:
ImageIO.write(image, "gif", byteArrayO);
image = null;
byte [] byteArray = byteArrayO.toByteArray();
byteArrayO = null;
...
Run Code Online (Sandbox Code Playgroud)