Java 使用BuffereImage加载映像时ram使用率高
我创建了一个程序,可以用FileDialog加载图像,调整其大小,向用户预览图像,然后单击按钮将其保存到文件夹中 我的问题是:Java 使用BuffereImage加载映像时ram使用率高,java,swing,bufferedimage,ram,Java,Swing,Bufferedimage,Ram,我创建了一个程序,可以用FileDialog加载图像,调整其大小,向用户预览图像,然后单击按钮将其保存到文件夹中 我的问题是: 当我运行我的程序时-RAM使用量~50mb 正在加载1mb JPG文件-RAM使用量~93mb 保存1mb JPG文件-RAM使用量~160mb 我希望这个程序是轻量级的,但是在3-4个文件之后,它会占用500mb的RAM空间 我尝试使用System.gc()每次用户保存文件时,它都会将RAM使用量减少约10% 下面是一个加载和保存图像的代码,完整的代码,你可以找到 顺
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()
保存图像的代码:
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就是这样工作的。(承诺内存将返回到操作系统?)正如@Andrew Thompson在评论部分指出的,如果您想要更少的内存消耗,请看一下这个。如果您运行它,您将看到,由于内存限制,它不会消耗太多。这实际上告诉你不要担心。JVM将发挥它的魔力,并根据操作系统所说的空闲内存量来处理内存消耗
如果它仍然困扰着你,你可以尝试找到任何行为可能不同的ImageIO
替代方案。但在我看来,这不值得你这么做。我的意思是,你只想保存/加载一个图像
另一个值得一读的问题是我不建议使用空的捕捉块。至少要记录异常。您应该记住jpg是一种压缩图像格式。将其解压缩到BuffereImage时,每个像素可能由4个整数值(RGBA)表示,具体取决于您的图像格式/颜色空间。这意味着100x100像素图像占用40000个整数值。
ImageIO.write
可能是罪魁祸首。这不一定是泄漏,JVM可能只是不释放资源。您可以忘记System.gc()
,这仅仅是一个建议,不可靠,并且广泛建议不要使用。@Mär-有没有更好的方法来保存映像并在以后释放资源?“我打算这个程序是轻量级的,但在3-4个文件之后它会占用500mb的RAM空间。”然后用有限的RAM启动JVM!JVM只有在看到需要时才会使用GC。看,谢谢!我会照你说的做。我将我的VM参数设置为-Xmx200m,正如预期的那样,程序在260mb下运行。我将尝试找到比ImageIO
更好的解决方案。我只是希望有某种方法来限制程序中的RAM,而不是JVM的起始参数:)与其说ImageIO
使用了很多内存,不如说将解码后的像素保留在内存中(就像BufferedImage
那样)需要一定数量的内存(宽度*高度*字节/像素)。