java - 使用 BufferedImage 加载图像时内存使用率高
问题描述
我创建了一个程序,它使用FileDialog加载图像、调整大小、预览给用户,然后单击按钮将其保存到文件夹中。
我的问题是:
- 当我运行我的程序时 - RAM 使用量 ~50mb
- 加载 1mb JPG 文件 - RAM 使用量 ~93mb
- 保存 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()
解决方案
“问题”是ImageIO
那种使用大量内存。然后这个内存将不会返回给操作系统(这就是为什么即使不需要调用System.gc()
也不会返回它)因为这就是 JVM 的工作方式。(Java 13承诺内存将返回给操作系统?)正如@Andrew Thompson 指出的那样在评论部分,如果你想减少内存消耗,看看这个问题。如果你运行它,你会看到内存限制它不会消耗太多。这实际上告诉你不要担心。JVM 将发挥它的魔力,并根据操作系统所说的空闲内存量来处理内存消耗。
如果它仍然困扰您,您可以尝试找到任何ImageIO
可能表现不同的替代方案。但在我看来,这不值得你的需求。我的意思是,您只想保存/加载图像。
另一个值得一读的问题是为什么调用 System.gc() 是不好的做法?
推荐阅读
- docker - pwa-studio docker 配置 dev-environmet
- apache-kafka - 将不同时间出现的记录加入 Kafka 流
- android - 列表视图可以处理太多项目吗?
- flask - 烧瓶 - 数据库条目的简单删除 - 缺少位置参数
- c# - 如何在 MSTests 中忽略
- javascript - 当 catch 返回错误时重新启动 then() 块
- vue.js - 如何使用两个 v-navigation-drawer?
- c++ - 由于内存映射,无法处理视频或 Videopath
- python - 基于Django函数的视图分页不起作用
- angular - 在 nz-row 和 nz-col 上构建和服务失败