Hey,
Ich versuche um ganz viele kleine unabhängige Aufgaben parallel zu erledigen einen ThreadPool zu verwenden und benutze dafür einen ThreadPoolExecutor mit fester Größe (4).
Nun kann ich ab einem entsprechend hohen Workload folgende Meldungen beobachten:
Danach sehe ich noch mehr solcher Exceptions, bis dann irgendwann (nach ein paar Sekunden) wieder ein paar Aufgaben erledigt werden, wobei zwischendurch immer sowas im Log auftaucht:
So erstelle ich den ThreadPool
Ich verstehe zwei Sachen nicht. Erstens warum z.B. "Thread-10" in der Meldung auftaucht, es sollten doch eigentlich nur 4 sein. Und wie kommt das OutOfMemory Problem zu Stande?
Falls es auch interessant ist was in den Worker Thread gemacht wird:
Ich lade Bilder von der Festplatte und skaliere diese mit "progressive bilinear scaling" um das Programm responsive zu halten werden die einzelnen Skalierungen in die Worker Queue des ThreadPoolExecutors eingereiht. Jedenfalls funktioniert alles noch wunderbar, wenn ich ca. 50 Bilder auf diesem Wege importiere (ca. 180Mb), sobald ich es aber mit 60-70 Bildern mache (ca.230Mb) fliegen die ganze Zeit diese OutOfMemoryExceptions.
Hier falls interessant noch der Code der tatsächlich in den WorkerThreads ausgeführt wird.
(alles was hier aus der Klasse GraphicsUtilities kommt, ist aus dem SwingX Projekt, wobei die "createThumbnail" Mehtode den Progressive Bilinear Scaling Algorithmus implementiert)
Ich hoffe jemand hat ne Idee (=
Danke schonmal.
Grüße,
sMau
Ich versuche um ganz viele kleine unabhängige Aufgaben parallel zu erledigen einen ThreadPool zu verwenden und benutze dafür einen ThreadPoolExecutor mit fester Größe (4).
Nun kann ich ab einem entsprechend hohen Workload folgende Meldungen beobachten:
Java:
Exception in thread "pool-1-thread-5" java.lang.OutOfMemoryError: Java heap space
at java.awt.image.DataBufferInt.<init>(DataBufferInt.java:75)
at java.awt.image.Raster.createPackedRaster(Raster.java:470)
at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1032)
at java.awt.GraphicsConfiguration.createCompatibleImage(GraphicsConfiguration.java:149)
at java.awt.GraphicsConfiguration.createCompatibleImage(GraphicsConfiguration.java:178)
at org.jdesktop.swingx.util.GraphicsUtilities.toCompatibleImage(GraphicsUtilities.java:321)
at org.jdesktop.swingx.util.GraphicsUtilities.loadCompatibleImage(GraphicsUtilities.java:270)
at de.netprojectev.Media.ImageFile.loadImageFileFromDisk(ImageFile.java:106)
at de.netprojectev.Media.ImageFile.generateDisplayImage(ImageFile.java:131)
at de.netprojectev.Media.ImageGenerationTask.run(ImageFile.java:45)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Java:
Exception in thread "pool-1-thread-10" java.lang.OutOfMemoryError: Java heap space
Java:
public static ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(4);
Ich verstehe zwei Sachen nicht. Erstens warum z.B. "Thread-10" in der Meldung auftaucht, es sollten doch eigentlich nur 4 sein. Und wie kommt das OutOfMemory Problem zu Stande?
Falls es auch interessant ist was in den Worker Thread gemacht wird:
Ich lade Bilder von der Festplatte und skaliere diese mit "progressive bilinear scaling" um das Programm responsive zu halten werden die einzelnen Skalierungen in die Worker Queue des ThreadPoolExecutors eingereiht. Jedenfalls funktioniert alles noch wunderbar, wenn ich ca. 50 Bilder auf diesem Wege importiere (ca. 180Mb), sobald ich es aber mit 60-70 Bildern mache (ca.230Mb) fliegen die ganze Zeit diese OutOfMemoryExceptions.
Hier falls interessant noch der Code der tatsächlich in den WorkerThreads ausgeführt wird.
(alles was hier aus der Klasse GraphicsUtilities kommt, ist aus dem SwingX Projekt, wobei die "createThumbnail" Mehtode den Progressive Bilinear Scaling Algorithmus implementiert)
Java:
protected void generatePreview() {
log.log(Level.INFO, "generating new thumbnail for " + name);
loadImageFileFromDisk();
int widthToScaleTo = Integer.parseInt(PreferencesHandler.getInstance().getProperties().getProperty(Constants.PROP_PREVIEW_SCALE_WIDTH));
preview = new ImageIcon(Misc.getScaledImageInstanceFast(loadedImage, widthToScaleTo , (int) (widthToScaleTo * loadedImage.getHeight(null))/loadedImage.getWidth(null)));
}
Java:
protected void loadImageFileFromDisk() {
if(loadedImage == null && path != null) {
log.log(Level.INFO, "loading image from hard disk " + name);
try {
loadedImage = GraphicsUtilities.loadCompatibleImage(new BufferedInputStream(new FileInputStream(path)));
} catch (FileNotFoundException e) {
log.log(Level.SEVERE, "imagefile could not be found on hard disk", e);
} catch (IOException e) {
log.log(Level.SEVERE, "error reading imagefile from hard disk", e);
}
}
}
Java:
public static BufferedImage getScaledImageInstanceFast(BufferedImage imageToScale, int newWidth, int newHeight) {
BufferedImage scaledImage;
int oldWidth = imageToScale.getWidth();
int oldHeight = imageToScale.getHeight();
if(oldWidth > newWidth && oldHeight > newHeight) {
scaledImage = GraphicsUtilities.createThumbnail(imageToScale, newWidth, newHeight);
} else {
scaledImage = GraphicsUtilities.createCompatibleImage(newWidth, newHeight);
Graphics2D g2 = scaledImage.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(imageToScale, 0, 0, newWidth, newHeight, null);
g2.dispose();
}
return scaledImage;
}
Ich hoffe jemand hat ne Idee (=
Danke schonmal.
Grüße,
sMau
Zuletzt bearbeitet: