Java ByteArrayOutputStream在内存中泄漏

问题描述 投票:1回答:4

我提出了一个新问题,因为这与我的上一个主题不同。我现在知道哪个问题更确切。

我创建一个新的bytearrayoutputstream

ByteArrayOutputStream byteArray = new ByteArrayOutputStream();

没什么特别的。然后,当我向其中写入图像时,这种方式

ImageIO.write(image, "gif", byteArray);

首先,内存增加了100 mb,而不是在日食中,而是在“现实”中。然后,每次我向该流或另一个流中写入新图像后,它就会缓慢增加!

一段时间后它停止工作并有点崩溃。

我已经尝试关闭它以及所有这些东西,刷新,重置所有内容,但是它仍然会泄漏内存。当我停止使用byteArray或将其为null时,我希望它脱离内存。

System.gc();

在这种情况下不会提供帮助。

[请帮助我,以及您需要知道的其他任何信息,我会回答,请返回并回复:)

java memory memory-leaks javax.imageio bytearrayoutputstream
4个回答
0
投票

您的使用模式应为:

while( keepRunning) {
     ByteArrayOutputStream byteArray = new ByteArrayOutputStream();   
     ImageIO.write(image, "gif", byteArray);
}

如果您这样做的速度比JVM收集垃圾的速度快,您最终将获得很长的GC暂停或OutOfMemory异常。


0
投票

您是否尝试过此方法:

 try{
  ByteArrayOutputStream baos = new ByteArrayOutputStream();
  ImageIO.write(image, "png", baos);
  baos.flush();
  byte[] imageBytes = baos.toByteArray();
  baos.close();
}catch(Exception ex){
  System.out.println(ex.getMessage());
}

0
投票

您在做什么没有任何意义。您正在从内存中取出图像,然后再次将其作为字节数组放入存储器。

您应该将该图像放入文件或通过网络发送。或者,如果您只想保留一个副本,请像我在此处描述的那样复制图像(而不是字节数组!):Bug in using Object.clone()


0
投票

请参阅similar answer I posted to another ByteArrayOutputStream question

ByteArrayOutputStream中没有允许您缩小缓冲区的方法。重置更改缓冲区中的位置

您的解决方案是

  1. 使用构造函数在使用前指定缓冲区的大小。将大型对象写入流时,这将节省大量内存并防止OOM异常。
  2. 如果要重用BAOS对象,请调用reset。这将使下一次写入从缓冲区的开头开始。
  3. 释放内存的唯一方法是删除对其的所有引用。在上面的代码中,您会说byteArray = null;
© www.soinside.com 2019 - 2024. All rights reserved.