简体   繁体   中英

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 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". 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.

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.

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

Please refer to a similar answer I posted to another ByteArrayOutputStream question .

There is no method in ByteArrayOutputStream that allows you to shrink the buffer. 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.
  2. If you want to reuse your BAOS object, call 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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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