Input/Output ImageIO.load frisst meinen ganzen Speicher weg!

Hutmacher

Bekanntes Mitglied
Ich habe - auf die Grundlagen heruntergebrochen - ein Programm, welches ein Bild anzeigt und bei ich über Datei -> Öffnen ein Bild auswählen und laden kann. Lade ich ein neues, wird das alte einfach ersetzt. Das geschieht per ImageIO:
Java:
try {
    BufferedImage i = ImageIO.read(new File("images/season.jpg"));
} catch (IOException e) {
    e.printStackTrace();
}

Nun lade ich ein großes Bild (2000x8000px). Nach dem Laden verbraucht es seine ~70 MB im Speicher - das ist auch okay und vollkommen logisch. Wenn ich nun allerdings das gleiche Bild noch einmal lade, sind es auf einmal ~120 MB. Wenn ich es nochmal lade, sind es ~190 und es schraubt sich immer höher.

Führt einmal Folgendes Snippet aus, am besten mit einem großen Bild, und beobachtet den Speicherverbrauch im Taskmanager. Nach 30 Sek. des Laufens hat sich das Snippet auf ~550MB RAM hochgeschraubt. Dann kommt irgendwann der GC dazu und senkt es um ~80MB, dann steigt es wieder etwas usw.
Java:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Test {
	public static void main(String[] args) {
		while (true)
		{
			try {
				BufferedImage i = ImageIO.read(new File("images/season.jpg"));
			} catch (IOException e) {
				e.printStackTrace();
			}	
			
			try { //kleine Erholung
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
Resultat:
Wenn ich in meinem Programm ein Bild öffne, etwas später ein anderes, danach wieder ein anderes, allokiert sich schnell mal ein Speicherverbrauch von 400MB. Wie kann ich dem Einhalt gebieten?
 

njans

Top Contributor
Du wunderst dich, wenn du ein Bild wieder und wieder von der Platte in den Speicher lädst, dass der Speicher voll läuft?
Der Grund, warum das Bild nicht sofort wieder vom GC gelöscht wird ist, dass der Ram nicht benötigt wird und die Garbage Collection in Java on-demand passiert. Wenn Java Ram braucht, springt der GC an und schaut, was sich machen lässt. Ansonsten kannst du nicht sicher sagen, wann der Müll aufgeräumt wird.

Wenn du das Bild brauchst: Lade es einmal ein und behalte es im Speicher solange du es brauchst.
 
Zuletzt bearbeitet:

DrZoidberg

Top Contributor
Ganz einfach. Starte dein Programm mit "java -Xmx256m Test". Dann wird der Speicherverbrauch auf 256 MB beschränkt. Ausserdem kannst du auch die flush Methode von BufferedImage verwenden um sicherzustellen, dass sämtlicher Speicher frei gegeben wird.
 
Zuletzt bearbeitet:

Hutmacher

Bekanntes Mitglied
Danke euch beiden. Ich wusste, dass der GC irregulär läuft und auch nicht direkt befehligt, sondern nur angestupst, werden kann und auch dann läuft, wenn Speicher wieder freigegeben werden muss.

Ich dachte aber immer, wenn ich
Object x = "Bla";
habe, und dann
x = "Abc";
schreibe, dann das "Bla" im Speicher überschrieben würde.

Der Trick mit dem VM-Switch ist ja nett :)
 

njans

Top Contributor
Java verwaltet Speicher selbst, du kannst, ohne Zuhilfenahme externer Libraries nicht in speziellen Bereiche des Speichers schreiben. Und das was du da überschreibst, ist eine Referenz auf ein Objekt, kein Objekt selbst.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Bild in Jar-File mit ImageIO Java Basics - Anfänger-Themen 50
R Input/Output ImageIO kommt mit pic_url nicht klar Java Basics - Anfänger-Themen 10
R ImageIO.read Fehler Java Basics - Anfänger-Themen 4
M Probleme mit ImageIO Java Basics - Anfänger-Themen 11
M Pfad angabe bei getRescource und ImageIO.write Java Basics - Anfänger-Themen 4
B Exception bei ImageIO wegen sonderzeichen Java Basics - Anfänger-Themen 11
G Lesefehler von ImageIO! Java Basics - Anfänger-Themen 7
G ImageIO.write() Java Basics - Anfänger-Themen 2
D ImageIO metadata auslesen aus png image Java Basics - Anfänger-Themen 2
I ImageIO.write(bild, "was gibts da alles", pfad); Java Basics - Anfänger-Themen 6
F javax.imageio.ImageIO write methode Java Basics - Anfänger-Themen 11
T IntelliJ / SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". Java Basics - Anfänger-Themen 4
I Erste Schritte Native code library failed to load beim Ausführen eines Beispiels Java Basics - Anfänger-Themen 5
B Linux - Error: Could not find or load main class application.Main Java Basics - Anfänger-Themen 28
P Compiler-Fehler Could not load or find main class fehler Java Basics - Anfänger-Themen 15
P Compiler-Fehler could not find or load main class Java Basics - Anfänger-Themen 5
C Android APP - Load More Button und beschleunigung... Java Basics - Anfänger-Themen 2
O could not load jvm Java Basics - Anfänger-Themen 4
Spin XML load does not work Java Basics - Anfänger-Themen 3
G Cannot load 64-bit SWT libraries on 32-bit JVM Java Basics - Anfänger-Themen 3
N Konstruktor mit filename bzw. methode load(filename) Java Basics - Anfänger-Themen 11
Y Failed to load mein class manifest from. Java Basics - Anfänger-Themen 17
J Java Anwendung starten ""faild to load main class Java Basics - Anfänger-Themen 15
T Failed to load Main-Class manifest attribute from U.U.jar Java Basics - Anfänger-Themen 3
Z "Cannot load jvm.dll" hilfe !! Java Basics - Anfänger-Themen 3
S Hilfe es frisst meinen RAM! Java Basics - Anfänger-Themen 5

Ähnliche Java Themen

Neue Themen


Oben