Problem beim laden von vielen Bildern

Status
Nicht offen für weitere Antworten.

metaller

Mitglied
Hi Leute,

ich hab ein Problem beim Laden von Bildern in ein Applet. Das Applet soll die Bilder als kleine Vorschau anzeigen.
Und solange ich wenig Bilder lade, geht auch alles gut. Sobald ich mehr Bilder laden kriege ich bei folgende Fehlermeldung.

Exception in thread "Thread-XY" java.lang.OutOfMemoryError: Java heap space

Die ersten ca. 20 Bilder werden fehlerfrei geladen. Danach geht gar nix mehr.

Die Bilder lade ich Verzeichnisweise mit einer for schleife:
Code:
		File f = new File(directory);
		File[] fList = f.listFiles();
		for (int i = 0; i < fList.length; i++) {
			try {
				String name = fList[i].getName();
				String ext = name.substring(name.lastIndexOf("."))
						.toLowerCase();
				int typ = 0;
				if (ext.equals(".jpg"))
					typ = Picture.JPG;
				if (ext.equals(".bmp"))
					typ = Picture.BMP;
				if (ext.equals(".gif"))
					typ = Picture.GIF;
				if (ext.equals(".png"))
					typ = Picture.PNG;
				if (ext.equals(".tif"))
					typ = Picture.TIF;
				if (typ != 0)
					addBildObjekt(fList[i].getAbsolutePath(), fList[i]
							.length(), typ);
			} catch (java.lang.StringIndexOutOfBoundsException e) {}

dann wird das Ganze noch ein bischen weiter übergeben und dann kommt das laden:

Code:
public void loadImage(String path) {
		double scale = 0;
		switch (typ) {
		case JPG:
		case GIF:
		case PNG:
			ImageIcon image = new ImageIcon(path);
			this.width = image.getIconWidth();
			this.height = image.getIconHeight();
			this.width = 100;
			this.height = 100;
			if (width / 80.00 > height / 60.00)
				scale = width / 80.00;
			else
				scale = height / 60.00;
			this.iiBild = image.getImage().getScaledInstance(
					(int) (width / scale), (int) (height / scale),
					Image.SCALE_FAST);
			iiBild.flush();
			break;
		case BMP:
		case TIF:
			Image temp = Jimi.getImage(path);
			this.width = temp.getWidth(this);
			this.height = temp.getHeight(this);
			if (width / 80.00 > height / 60.00)
				scale = width / 80.00;
			else
				scale = height / 60.00;
			this.iiBild = temp.getScaledInstance(
					(int) (width / scale), (int) (height / scale),
					Image.SCALE_FAST);
			temp.flush();
			break;
		}
	}

Ich hab schon mit flush() versucht die Speicher wieder freizugeben. Aber irgendwie werden die anscheinend doch gecacht. Ich hab schon gegooglet aber irgendwie nich das gefunden was ich gesucht hab.

Das einzige was ich gefunden hab waren vielleicht die verwendung von VolatileImage oder einfach der Vergrößerung des Heap Space.

Wäre cool wenn jemand eine Idee hätte was ich ändern muss denn ich weiß nicht mehr was ich machen soll. Danke im vorraus.
 
Wie groß sind die Bilder denn? (nicht in kb, sondern in pixel).
Wenn sie den Heap komplett füllen kann man nämlich nichts machen. Du kannst eben keinen Speicher herzaubern.
 
Ich hab jetzt mit jetzt mal den Speicherstand anzeigen lassen (zumindest wenn das die richtigen Methoden sind)

Code:
System.out.println("max:"+Runtime.getRuntime().maxMemory()/1024.0/1024.0);
System.out.println("free"+Runtime.getRuntime().freeMemory()/1024.0/1024.0);

Und das ergebnis war 64Mb Heap Space und nachdem ich die Bilder ins Vorschaufenster geladen hab, sind noch 22MB frei. Das heißt ja das die Bilder ca. 42MB groß sind minus das bischen was das Applet selbst braucht. Das Lustige is aber das die Bilder in Orginalgröße insgesamt nur 30MB groß sind.
 
metaller hat gesagt.:
Und das ergebnis war 64Mb Heap Space und nachdem ich die Bilder ins Vorschaufenster geladen hab, sind noch 22MB frei. Das heißt ja das die Bilder ca. 42MB groß sind minus das bischen was das Applet selbst braucht. Das Lustige is aber das die Bilder in Orginalgröße insgesamt nur 30MB groß sind.
Was du natürlich überhaupt nicht vergleichen kannst, da die Originale komprimiert sind :wink:
 
Ganz genau! 😀 😳

Ja aber das Komische is ja auch das die Bilder die er sich im Speicher halten soll nur 60 * 80px sind, und ich die Vermutung hab, das die großen Orginalbilder irgendwo gecacht werden obwohl ich sie flushe, warum auch immer. Denn von den 60*80ern müsst ich doch problemlos mindestens 100 speichern können bei 64MB.
 
Sehe ich auch so. Die Bilder sind zu klein um alleine den Speicher vollzumüllen.
Versuch mal ein paar manuelle GC Aufrufe und zieh dir einen Heap Dump mit einem Profiler, dann sieht man eventuell weiter.
 
Ja, das mit dem gc() hatte ich schonmal versucht, hatte aber nix gebracht.
Und ich hab das Ganze jetzt mal mit dem Eclipse Profiler profiled. Aber ich weiß nich genau auf was ich da gucken muss oder ob ich die richtigen Einstellungen gemacht hab. ???:L Gibts da nen Link wo das gut erklärt is?
 
Wegen des Speicherproblems hätt ich da ne Lösung!
Gib eclipse einfach mehr speicher 😀

unter %ECLIPSE_HOME% gibt es ne eclipse.ini.
dort stehen ein paar werte drin
Xms ist der StandardSpeicher, den eclipse belegt
Xmx ist der ExtendedSpeicher, welcher maximal belegt wird.

ich hab beide etwas erhöht. (Xms auf 128 und Xmx auf 512)
 
Hat denn jemand eine Idee, wie man den OutOfMemoryError abfangen bzw. umgehen kann, ich kann ja nicht einfach ne try catch drumsetzten. Und über
Code:
if(Runtime.getRuntime().totalMemory()>Runtime.getRuntime().maxMemory)
kann ich das auch irgendwie nich abfangen.
 
So Leute, ich hab's endlich gelöst. Hab die Bilder mal anders geladen.
Hatte bis jetzt immer

Code:
Image temp = Jimi.getImage(path, Jimi.SYNCHRONOUS);

hab jetzt aus lauter Verzweiflung einfach mal

Code:
Image temp = Jimi.getImage(path, Jimi.ONE_SHOT);

genommen. habe eigentlich gedacht das bei synchronem Laden der Speicher wieder freigegeben wird, hab mich wohl getäuscht :roll: 😀 . Naja jetzt geht's auf jeden Fall.
Nochma danke für eure Lösungsvorschläge.
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben