简体   繁体   English

Java ByteArrayOutputStream 在内存中泄漏

[英]Java ByteArrayOutputStream leaks in memory

I made a new question because this is different from my last thread.我提出了一个新问题,因为这与我的上一个线程不同。 I now know what th e problem is more exact.我现在知道更确切的问题是什么。

I create a new bytearrayoutputstream我创建了一个新的 bytearrayoutputstream

ByteArrayOutputStream byteArray = new ByteArrayOutputStream();

Nothing special.没什么特别的。 Then, when I write an image to it, this way然后,当我给它写一个图像时,这样

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

the memory increases like 100 mb first, not in eclipse, but in "reality".内存首先增加 100 mb,不是在日食中,而是在“现实”中。 Then it slowly increases after that each time I write a new image to that stream OR another!!然后每次我向该流或另一个流写入新图像时它会慢慢增加!!

and after a while it stops working and kinda crashes.一段时间后它停止工作并且有点崩溃。

I have tried closing it and all that, flushing, reseting, everything, but it still leaks memory.我试过关闭它和所有这些,刷新,重置,一切,但它仍然泄漏内存。 I want it to get away from memory when I stop using byteArray or null it.当我停止使用 byteArray 或将其设为 null 时,我希望它远离内存。

System.gc();

wont help in this case.在这种情况下不会有帮助。

Please help me and anything else you need to know I will answer and please return and reply back :)请帮助我以及您需要知道的任何其他信息,我会回答,请返回并回复:)

Your usage pattern should be like:你的使用模式应该是这样的:

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

If you do this faster than the JVM can collect garbage you'll eventually get a very long GC pause or an OutOfMemory exception.如果你这样做的速度比 JVM 收集垃圾的速度快,你最终会得到一个很长的 GC 暂停或 OutOfMemory 异常。

Have you tried this:你有没有试过这个:

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

What you are doing doesn't make any sense.你在做什么没有任何意义。 You're taking an image out of memory and put it into memory again, this time as byte array.您正在从内存中取出图像并再次将其放入内存,这次是作为字节数组。

You should put that image into a file or send over the network.您应该将该图像放入文件或通过网络发送。 Or, if you want just hold a copy, copy the image (not the byte array!) like I described here: Bug in using Object.clone()或者,如果您只想保留副本,请复制图像(而不是字节数组!),就像我在此处描述的那样: 使用 Object.clone() 的错误

Please refer to a similar answer I posted to another ByteArrayOutputStream question .请参考我发布到另一个 ByteArrayOutputStream 问题类似答案

There is no method in ByteArrayOutputStream that allows you to shrink the buffer. ByteArrayOutputStream 中没有允许您缩小缓冲区的方法。 Reset changes the position in the buffer .重置更改缓冲区中位置

The solution for you is to您的解决方案是

  1. Use the constructor to specify the size of the buffer before use.使用前使用构造函数指定缓冲区的大小。 When you are writing large objects to the stream, this will save a lot of memory and prevent OOM exceptions.当您将大对象写入流时,这将节省大量内存并防止 OOM 异常。
  2. If you want to reuse your BAOS object, call reset.如果您想重用您的 BAOS 对象,请调用 reset。 That will make the next write start at the beginning of the buffer.这将使下一次写入在缓冲区的开头开始。
  3. The only way to free the memory is to remove all references to it.释放内存的唯一方法是删除对它的所有引用。 In the code above, you would say byteArray=null;在上面的代码中,你会说 byteArray=null;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM