内存中的Java ByteArrayOutputStream泄漏

内存中的Java ByteArrayOutputStream泄漏,java,memory,memory-leaks,javax.imageio,bytearrayoutputstream,Java,Memory,Memory Leaks,Javax.imageio,Bytearrayoutputstream,我提出了一个新问题,因为这与我的上一个帖子不同。我现在知道什么问题更确切了 我创建了一个新的bytearrayoutputstream ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); 没什么特别的。 然后,当我给它写一个图像时,这样 ImageIO.write(image, "gif", byteArray); 内存先增加100 mb,不是在eclipse中,而是在“现实”中。然后,每次我将一个新图像写入该流或另一

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

我创建了一个新的bytearrayoutputstream

ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
没什么特别的。 然后,当我给它写一个图像时,这样

ImageIO.write(image, "gif", byteArray);
内存先增加100 mb,不是在eclipse中,而是在“现实”中。然后,每次我将一个新图像写入该流或另一个流时,它都会慢慢增加

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

我尝试过关闭它和所有的一切,刷新,重置,一切,但它仍然泄漏内存。当我停止使用byteArray或将其设为null时,我希望它从内存中消失

System.gc();
在这种情况下没有帮助


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

您的使用模式应该是:

while( keepRunning) {
     ByteArrayOutputStream byteArray = new ByteArrayOutputStream();   
     ImageIO.write(image, "gif", byteArray);
}
如果这样做的速度比JVM收集垃圾的速度快,那么最终会出现很长的GC暂停或OutOfMemory异常。

您是否尝试过这样做:

 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());
}

你所做的毫无意义。您正在从内存中取出一个图像,并将其再次放入内存,这次是作为字节数组

您应该将该图像放入文件或通过网络发送。或者,如果您只想保存一个副本,请复制图像(而不是字节数组!),就像我在这里描述的那样:

请参阅

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

你的解决办法是

  • 使用构造函数在使用前指定缓冲区的大小。当您将大型对象写入流时,这将节省大量内存并防止OOM异常
  • 如果要重用BAS对象,请调用reset。这将使下一次写入从缓冲区的开头开始
  • 释放内存的唯一方法是删除对它的所有引用。在上面的代码中,您会说byteArray=null
    在这种情况下,您不需要手动调用
    System.gc()
    。如果您已经关闭了所有未使用的资源/流/等,那么您应该不会有问题。试着增加Java内存的限制。您可能在未显示的代码中出错。您不应该调用System.gc()…Java提供了自动gc函数。只要取消对变量的引用。此外,请包括更多的代码可能重复的nope。没那么快。也许每隔一秒钟我就做一次。但在那之后,我关闭了它。无论如何,我可以使用相同的bytearrayoutputstream并在每次使用它的数据时重置它?你现在正在重置它吗?重置不会删除任何已分配的现有内存,但会覆盖现有的基础字节[]缓冲区。那么如何删除它呢?您需要显示一个更大的已剪切代码,以真正了解您正在执行的操作。它应该显示ByteArrayOutputStream的初始化位置和更新位置/时间。执行相同的操作。仍然在记忆中结束