High ram usage when loading image with BufferedImage

I have created a program that loads image with FileDialog, resize it, previews it to users, and after button click saves it to a folder.

My problem is:

  1. when I run my program – RAM usage ~50mb
  2. loading 1mb JPG file – RAM usage ~93mb
  3. saving 1mb JPG file – RAM usage ~160mb

I intend this program to be lightweight, but after 3-4 files it occupies 500mb RAM space.

I tried to use System.gc(); every time user saves file, but it reduced RAM usage only by ~10%.

Below is a code with loading and saving images, full code, you can find HERE.

BTW – why when after loading 1mb JPG and then saving it size increase to 10mb?

Code for loading image:

    FileDialog imageFinder = new FileDialog((Frame)null, "Select file to open:");
            imageFinder.setFile("*.jpg; *.png; *.gif; *.jpeg");
            imageFinder.setMode(FileDialog.LOAD);
            imageFinder.setVisible(true);
            userImagePath = new File(imageFinder.getDirectory()).getAbsolutePath()+"\"+imageFinder.getFile();

            userImagePath = userImagePath.replace("\", "/");

Code for saving image:

 BufferedImage bimage = new BufferedImage(userImage.getWidth(null), userImage.getHeight(null), BufferedImage.TYPE_INT_ARGB);

                    Graphics2D bGr = bimage.createGraphics();
                    bGr.drawImage(userImage, 0, 0, null);
                    bGr.dispose();

                    try {
                        BufferedImage bi = bimage;
                        File outputfile = new File("C:\Users\Mariola\git\MySQL-viwer\MySQL viewer\src\database_images\"+userBreedInfo[0]+".jpg");
                        ImageIO.write(bi, "png", outputfile);
                    } catch (IOException e1) {

                    }
            }
            System.gc()

Answer

The “problem” is that ImageIO kind of uses much memory. Then this memory will not be returned to the OS (that’s why even a no-need call to System.gc() will not return it) because that’s how JVM works.(Java 13 promises that memory will be returned to the OS?) As @Andrew Thompson pointed out in the comment section, if you want less memory consumption take a look at this question. If you run it you will see that with memory limit it will not consume so much. Which actually tells you not to worry about it. JVM will do its magic and will handle memory consumption according to how much memory the OS says its free.

If it still bothers you, you could try to find any ImageIO alternatives that may behave differently. In my opinion though, it does not worth it for your needs. I mean, you just want to save/load an image.

Another worth-to-read question is Why is it bad practice to call System.gc()?

Leave a Reply

Your email address will not be published. Required fields are marked *