使用 BufferedImage 加载图像时 ram 使用率高

High ram usage when loading image with BufferedImage

我创建了一个使用 FileDialog 加载图像的程序,调整它的大小,向用户预览它,然后在单击按钮后将它保存到一个文件夹中。

我的问题是:

  1. 当我 运行 我的程序时 - RAM 使用 ~50mb
  2. 正在加载 1mb JPG 文件 - RAM 使用率~93mb
  3. 保存 1mb JPG 文件 - RAM 使用量 ~160mb

我打算这个程序是轻量级的,但是在 3-4 个文件之后它占用 500mb RAM space。

我尝试在每次用户保存文件时使用 System.gc();,但它只减少了 ~10% 的 RAM 使用率。

下面是加载和保存图像的代码,完整代码,你可以找到HERE

顺便说一句 - 为什么在加载 1mb JPG 然后保存后大小增加到 10mb?

图片加载代码:

    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("\", "/");

图片保存代码:

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

"problem" 是 ImageIO 那种占用大量内存的。然后这个内存将不会 returned 到 OS (这就是为什么即使不需要调用 System.gc() 也不会 return 它)因为这就是 JVM 的工作方式。( 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。如果你 运行 它你会看到有内存限制它不会消耗那么多。这实际上告诉你不要担心它。JVM 会发挥它的魔力并根据OS 表示它有多少内存可用。

如果它仍然困扰您,您可以尝试找到任何 ImageIO 可能表现不同的替代方案。但在我看来,它不值得满足您的需求。我的意思是,您只想 save/load 一张图片。

另一个值得一读的问题是Why is it bad practice to call System.gc()?