1

我提出了一个新问题,因为这与我的最后一个线程不同。我现在知道这个问题更准确。Java BufferedArrayOutputStream在内存中泄漏

我创建了一个新的bytearrayoutputstream

ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); 

没什么特别的。 然后,当我写的图像给它,这样

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

内存增加,如100 MB首先,不要在日食,但在“现实”。然后,在每次我向该流或另一个流写入新图像时,它会慢慢增加!

经过一段时间它停止工作,有点崩溃。

我已经尝试关闭它,所有的,冲洗,重置,一切,但它仍然泄漏内存。当我停止使用byteArray或将它清空时,我希望它远离内存。

System.gc(); 

不会帮助在这种情况下。

请帮我和其他任何你需要知道我要回答,请返回并回信:)

+0

在这种情况下,您不需要手动调用'System.gc()'。如果你关闭了所有未使用的资源/流/等,那么你应该没问题。尝试增加对Java内存的限制 – nevets1219 2012-08-14 17:58:57

+2

YOu应包含更多代码 – leonbloy 2012-08-14 18:00:05

+0

我同意。你可能在未显示的代码中做错了事。 – 2012-08-14 18:10:23

回答

0

你的使用模式应该是这样的:

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

如果你这样做快于JVM可以收集垃圾,最终会得到非常长的GC暂停或OutOfMemory异常。

+0

nope。没那么快。也许一次我做那个。但之后,我关闭它。 – 2012-08-14 17:59:48

+0

无论如何,我可以使用相同的bytearrayoutputstream并每次使用它的数据重置它? – 2012-08-14 18:01:05

+0

你现在重置吗?重置不会摆脱已分配的任何现有内存,但会覆盖现有的基础byte []缓冲区。 – Dave 2012-08-14 18:10:42

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

也一样。仍然在内存中结束 – 2012-08-14 18:39:06

0

你在做什么并没有任何意义。您将图像从内存中取出并重新放入内存,这次是字节数组。

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

0

请参阅similar answer I posted to another ByteArrayOutputStream question

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

为您的解决方案是

  1. 使用构造使用前指定缓冲区的大小。当您将大对象写入流时,这将节省大量内存并防止出现OOM异常。
  2. 如果您想重新使用您的BAOS对象,请致电重置。这将使下一次写入开始于缓冲区的开始处。
  3. 释放内存的唯一方法是删除对它的所有引用。在上面的代码中,你会说byteArray = null;