Java 데스크톱 기반 응용 프로그램을 개발 중입니다. 여기 내 작업은 이미지를 JLabel
에 넣는 것입니다. 레이블에 60 개 이상의 이미지를로드하면 자바는 "힙 공간 오류"를 표시합니다 (아래 참조).BufferdImage 힙 공간 오류
JDK의 힙 공간 크기를 늘리고 싶지 않습니다. 그냥 JLabel
에 이미지를 표시 한 후 메모리를 비우고 싶습니다. BufferedImage
에 flush()
을 사용했습니다. 메모리를 지우지 않습니다. 여기
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());
}
: (JPG/PNG 형식으로 압축 된 이미지 데이터보다 훨씬 더 큰)
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
java.lang.OutOfMemoryError와 이외에 전체 오류 메시지를 추가) 가시성 이벤트 기간 동안 창조적 인 일을. (DataBufferByte.java:92) java.awt.image.ComponentSampleModel.createDataBuffer에서 \t (ComponentSampleModel.java:415) java.awt.image.Raster.createWritableRaster에서 \t (Raster.java:944)에서 javax의 \t .imageio.ImageTypeSpecifier.createBufferedImage (ImageTypeSpecifier.java:1073) javax.imageio.ImageReader.getDestination에서 \t (ImageReader.java:2896) com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal에서 \t (JPEGImageReader.java : 998) \t com.sun.imageio.plugins.jpeg.JPEGImageReader.read (JPEGImageReader.java:966) –
'ImageIcon'을 사용하는'JLabel'은 여러분이 null 일 경우에도'img' 참조를 유지합니다 전자 참조. 다시 칠할 때마다 이미지 데이터가 다시 필요합니다. 'BufferedImage'를 flush()하는 것은 힙 메모리를 해제하지 않으므로 좋지 않습니다. 또한 JVM은 포기하고 OOME을 던지기 전에 GC를 수행해야하므로 명시적인 GC를 요청할 필요가 없습니다. 아이콘이있는'JLabel'을 없애거나 JVM 힙 크기를 늘리면됩니다. – haraldK