我正在開發基於Java桌面的應用程序。在這裏,我的工作是將圖像放入JLabel
。如果我將超過60張圖像加載到標籤中,則java會顯示「堆空間錯誤」(請參閱下面的內容)。BufferdImage堆空間錯誤
我不想增加JDK的堆空間大小。我只想在顯示JLabel
中的圖像後釋放內存。我用flush()
爲BufferedImage
:它不清除內存。
這裏是我碼
public static void setImageInLabelFromBufferedImage(JLabel label, int commonWidth, int maxImageHeight, BufferedImage img) {
try {
if (img.getWidth() < commonWidth && img.getHeight() < maxImageHeight) {
**img = Scalr.resize(img, Scalr.Mode.AUTOMATIC, img.getWidth(), img.getHeight(), Scalr.OP_ANTIALIAS);**
} else {
if (img.getWidth() > img.getHeight()) {
if (img.getWidth() > commonWidth) {
img = Scalr.resize(img, Scalr.Mode.FIT_TO_WIDTH, commonWidth, maxImageHeight, Scalr.OP_ANTIALIAS);
}
} else if (img.getHeight() > img.getWidth()) {
if (img.getHeight() > maxImageHeight) {
img = Scalr.resize(img, Scalr.Mode.FIT_TO_HEIGHT, commonWidth, maxImageHeight, Scalr.OP_ANTIALIAS);
}
} else {
img = Scalr.resize(img, Scalr.Mode.FIT_EXACT, commonWidth, maxImageHeight, Scalr.OP_ANTIALIAS);
}
}
//BufferedImage resizedImage = Scalr.resize(img, Scalr.Mode.AUTOMATIC, commonWidth, maxImageHeight, Scalr.OP_ANTIALIAS);
label.setIcon(new ImageIcon(img));
label.revalidate();
img.flush();
img = null;
Runtime.getRuntime().gc();
} catch (Exception e) {
log.error("setImageInLabelFromBufferedImage==>" + e.getMessage());
}
堆棧跟蹤:
java.lang.OutOfMemoryError: Java heap space at
java.awt.image.DataBufferByte.<init>(DataBufferByte.java:92) at
java.awt.image.ComponentSampleModel.createDataBuffer(ComponentSampleModel.java:415) at
java.awt.image.Raster.createWritableRaster(Raster.java:944) at
javax.imageio.ImageTypeSpecifier.createBufferedImage(ImageTypeSpecifier.java:1073) at
javax.imageio.ImageReader.getDestination(ImageReader.java:2896) at
com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:998) at
com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:966)
也許除了添加完整的錯誤消息的代碼 – Chris 2014-09-25 10:08:15
java.lang.OutOfMemoryError:在java.awt.image.DataBufferByte中的Java堆空間 \t。(DataBufferByte.java:92) \t在java.awt.image.ComponentSampleModel.createDataBuffer(ComponentSampleModel.java:415) \t在java.awt.image.Raster.createWritableRaster(Raster.java:944) \t在的javax .imageio.ImageTypeSpecifier.createBufferedImage(ImageTypeSpecifier.java:1073) \t在javax.imageio.ImageReader.getDestination(ImageReader.java:2896) \t在com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java :998) \t at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:966) –
2014-09-25 10:40:31
即使你沒有使用'ImageIcon',你的'JLabel'也會保留在'img'引用上e本地參考。每次重繪都會再次需要圖像數據。 flush()'BufferedImage'不釋放堆內存,所以它不好。在放棄和拋出OOME之前,JVM也應該做GC,所以不需要明確的GC。對我來說,你需要用Icon來擺脫一些JLabel,或者只是增加JVM堆大小。 – haraldK 2014-09-26 09:35:00