首页 > 解决方案 > 使用 BufferedImage 加载图像时内存使用率高

问题描述

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

我的问题是:

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

我希望这个程序是轻量级的,但是在 3-4 个文件之后它会占用 500mb RAM 空间。

System.gc();每次用户保存文件时我都尝试使用它,但它仅将 RAM 使用量减少了约 10%。

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

顺便说一句 - 为什么在加载 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()

标签: javaswingbufferedimageram

解决方案


“问题”是ImageIO那种使用大量内存。然后这个内存将不会返回给操作系统(这就是为什么即使不需要调用System.gc()也不会返回它)因为这就是 JVM 的工作方式。(Java 13承诺内存将返回给操作系统?)正如@Andrew Thompson 指出的那样在评论部分,如果你想减少内存消耗,看看这个问题。如果你运行它,你会看到内存限制它不会消耗太多。这实际上告诉你不要担心。JVM 将发挥它的魔力,并根据操作系统所说的空闲内存量来处理内存消耗。

如果它仍然困扰您,您可以尝试找到任何ImageIO可能表现不同的替代方案。但在我看来,这不值得你的需求。我的意思是,您只想保存/加载图像。

另一个值得一读的问题是为什么调用 System.gc() 是不好的做法?


推荐阅读