Managing memory usage when getting many screenshots in Java

By : Paul

I'm developing a software in Java which continuously takes screenshots of the desktop, stores it in a BufferedImage objectt then writes it to jpg files. At some point, the program causes a java.lang.OutOfMemoryError: Java heap space exception. Since I take a screenshot and save it as a file I don't need the previous BufferedImage objects in memory anymore so I can throw them away. Java doesn't seem to recognize these objects so they probably are still in memory. Is there a way to remove these in the JVM's memory so it doesn't run out? Continuously calling System.gc() probably won't help. Any ideas?

Here's the code for reference:

public BufferedImage getScreenShot() {

    BufferedImage screenImage = null;
    try {

        GraphicsEnvironment ge= GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice[] screens=ge.getScreenDevices();
        Rectangle allScreenBounds=new Rectangle();
        for(GraphicsDevice screen: screens)
            Rectangle screenbounds = screen.getDefaultConfiguration().getBounds();
            allScreenBounds.height=Math.max(allScreenBounds.height, screenbounds.height);

        Robot robot = new Robot();
        screenImage = robot.createScreenCapture(allScreenBounds);
    } catch (Exception ex) {
        Logger.getLogger(Screen.class.getName()).log(Level.SEVERE, null, ex);
    return screenImage;

I then just have a loop that continuously calls the method to generate the BufferedImage object, resizes it, and writes it to a file like this:

  FileImageOutputStream out = new FileImageOutputStream(f);
  IIOImage image = new IIOImage(ImageUtils.resize(getScreenShot(), width, height),null, null);
  writer.write(null, image, iwp);
By : Paul

You just need to remove the reference variables of earlier used BufferedImage objects. Then Garbage Collector will automatically release the memory occupied by them when needed.

As you are continuously taking screen shots, so I think you will be having some sort of looping thing and you will only be creating new variables but the earlier used variables will also be present in memory, as their reference still exists.

So try removing their reference variables. Then when memory will be almost filled then Java Garbage Collector will automatically come into play and will release your memory for you.

By : GPS

Yeah, when the use of variable is completed, tell garbage collector that it is no more used. You can say that by referencing the object to null.

In your case after this line

writer.write(null, image, iwp); 

try adding this line

By : Jayy

This video can help you solving your question :)
By: admin