[英]Java ImageIO won't free ram after deleting image
我有一個程序,可以打開一些8k圖像並將其大小調整為200x200像素。 該程序運行良好,但問題是關閉每個圖像后它不會釋放內存,因此它會很快耗盡內存! (之后喜歡40張圖片)
我嘗試使用system.gc()刷新並將圖像設置為null,而且我不能使用ImageReader,因為圖像格式不正確,並且說jpeg圖像不是以0x01 0x11開頭以及其他一些數字。 同時啟用禁用ImageIO.usecatch也無濟於事。 我嘗試對圖像使用全局變量,但它也無濟於事。
我需要在線程中運行程序,但是在編輯一些圖像后,即使在單個線程上,它也會占用過多的內存。 我刪除了我確認與問題無關的多余代碼部分。
static public class ImageLoadingTask implements Callable<JPanel> {
private final URL url;
private final int i;
private final JPanel scrollPane;
ImageLoadingTask(int i, URL url, JPanel scrollPane) {
this.url = url;
this.i = i;
this.scrollPane = scrollPane;
}
@Override
public JPanel call() {
try {
BufferedImage image = ImageIO.read(url);
ImageIcon icon = new ImageIcon(setImage(image));
image.flush();
image = null;
jPanels[i] = new JPanel();
jPanels[i].setLayout(new BoxLayout(jPanels[i],
BoxLayout.Y_AXIS));
JLabel label = new JLabel();
label.setIcon(icon);
icon = null;
jPanels[i].add(label);
String name = "date";
if (name.length() > 35) {
name = name.substring(0, 32) + "...";
}
JLabel jLabel = new JLabel(name);
jPanels[i].add(jLabel);
scrollPane.add(jPanels[i]);
latch.countDown();
return jPanels[i];
} catch (Exception ex) {
ex.printStackTrace();
latch.countDown();
demo.infoBox("Failed to open file maybe file is open?",
"Error");
return new JPanel();
}
private static Image setImage(BufferedImage source) {
int height = 150;
int width = 150;
if (source.getHeight() / height > source.getWidth() / width) {
return source.getScaledInstance(source.getWidth() * height /
source.getHeight(), height, Image.SCALE_SMOOTH);
} else {
return source.getScaledInstance(width, source.getHeight() * width
/ source.getWidth(), Image.SCALE_SMOOTH);
}
}
我認為getScaledInstance()
可能會保留對原始圖像的引用,該圖像用於呈現該圖像的縮放版本。
您應該在setImage()
方法中嘗試做的是創建一個具有所需縮小比例的新BufferedImage
,然后使用此新BufferedImage
的createGraphics()
方法將縮放后的實例繪制到此新BufferedImage
。 然后返回新的,較小的BufferedImage
而不是縮放后的實例本身。
此時,您應該有一個新的小圖像,該圖像不包含對原始大圖像的任何引用,並且原始大圖像將可以由垃圾回收自由釋放。
private static Image setImage(BufferedImage source) {
int height = 150;
int width = 150;
Image scaledImage;
if (source.getHeight() / height > source.getWidth() / width) {
width = source.getWidth() * height / source.getHeight();
scaledImage = source.getScaledInstance(width, height, Image.SCALE_SMOOTH);
} else {
height = source.getHeight() * width / source.getWidth();
scaledImage = source.getScaledInstance(width, height, Image.SCALE_SMOOTH);
}
BufferedImage result = new BufferedImage(widht, height, BufferedImage.TYPE_INT_RGB);
result.createGraphics().drawImage(scaledImage, new AffineTransform(), null);
return result;
}
我只是用下面的代碼打開圖像,它解決了我的問題!
工具箱工具箱= Toolkit.getDefaultToolkit(); 圖片image = toolkit.getImage(url.getPath());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.