使用 BufferedImage 加载图像时 ram 使用率高
High ram usage when loading image with BufferedImage
我创建了一个使用 FileDialog 加载图像的程序,调整它的大小,向用户预览它,然后在单击按钮后将它保存到一个文件夹中。
我的问题是:
- 当我 运行 我的程序时 - RAM 使用 ~50mb
- 正在加载 1mb JPG 文件 - RAM 使用率~93mb
- 保存 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()?
我创建了一个使用 FileDialog 加载图像的程序,调整它的大小,向用户预览它,然后在单击按钮后将它保存到一个文件夹中。
我的问题是:
- 当我 运行 我的程序时 - RAM 使用 ~50mb
- 正在加载 1mb JPG 文件 - RAM 使用率~93mb
- 保存 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()?