Exception: OutOfMemoryError

UweA

Mitglied
Hallo,

ich erzeuge ein Array, das ca. 46MB an Nettodaten enthält.
Während der Erzeugung fällt der verfügbare Speicher in meinem System um ca. 1.5GB, es verbleiben aber ca. 3GB an freiem RAM. (Mit Windows TaskManager kontrolliert)
Ich erhalte aber folgende exception: "OutOfMemoryError: GC overhead limit exceeded..."
Muss man bei Java (bzw. Eclipse) den verwendbaren Speicher angeben?

Grüße,
Uwe

P.S.: Hier ist mein Code
Java:
	public static class sPeaks extends Structure {
		public double Frequency;
		public double Vdbr;
		public double Phase;
	}

	public static class sAudioStatistics extends Structure {
		public double Klirr;
		public double THD;
		public int NoOfPeaks;
		public sPeaks[] Peaks = new sPeaks[4096];
	} 

...
  AS = new sAudioStatistics();
  for (i=0; i<4096; i++)
    AS.Peaks[i] = new sPeaks(); 
  AudioStatistics =(sAudioStatistics[]) AS.toArray(500);
 
Zuletzt bearbeitet:
Der Fehler wird geschmissen, wenn in deinem Programm fast ausschließlich (nahezu hundert Prozent der Rechenzeit) nur der GarbageCollector arbeitet.
 
Ich hatte dieses Forum nach "outofmemoryerror" durchsucht, aber keinen Treffer erzielt. Ich habe jetzt erst herausgefunden, dass die Suche Groß-/Kleinschreibungsensitiv ist. Sorry.

Ich habe meinem Eclipse mal die Parameter "-Xms512M -Xmx4000M -XX😛ermSize=2000M -XX:MaxPermSize=3000M" hinzugefügt. Ich habe nun zwar keinen Absturz mehr aber dafür rennt sich die Kiste in der Zeile "AudioStatistics =(sAudioStatistics[]) AS.toArray(500);" tot. Na, "tot" stimmt nicht ganz, denn der rechnet immer noch. Und das seit min. 15 Minuten. Ist daran der GC schuld? Eigentlich sollte eine Arrayallokation mit 46MB auf einem Core_i7 keine Viertelstunde dauern. (Unter C dauert das ca. 1 ms...)

Grüße,
Uwe
 
Moin,

das Spannende ist auch hier der part "GC overhead limit exceeded" !!
Wenn Du Dir meinen Link mal bis zuende durchliest, findest Du die Option "-XX:-UseGCOverheadLimit"

Gruß Klaus
 
Moin Klaus,

mit "-XX:-UseGCOverheadLimit" erhalte ich nach ca. 15 Minuten "java.lang.OutOfMemoryError: Java heap space".
Letzlich genau das, was auch in dem Artikel beschrieben wurde.

Ich fürchte das das ".toArray(n)" hier schlicht überfordert ist. Wie es aussieht erzeugt der eine immensen Overhead. Selbst wenn der nicht abstürzen würde, kann ich eine Startzeit von mehreren Minuten nicht gebrauchen.

Gruß,
Uwe
 
nein, wenn der speicher voll ist. Java hat nicht ganzen speicher deines systems zur verfügung...

Ähm... Oracle sagt dazu aber was anderes:

Excessive GC Time and OutOfMemoryError

The parallel collector will throw an OutOfMemoryError if too much time is being spent in garbage collection: if more than 98% of the total time is spent in garbage collection and less than 2% of the heap is recovered, an OutOfMemoryError will be thrown. This feature is designed to prevent applications from running for an extended period of time while making little or no progress because the heap is too small. If necessary, this feature can be disabled by adding the option -XX:-UseGCOverheadLimit to the command line.

Siehe hier:
Java SE 6 HotSpot[tm] Virtual Machine Garbage Collection Tuning
 
Zuletzt bearbeitet:
Mal davon abgesehen, mir ist der Code auch zu knapp, um wirklich zu erkennen, was du genau vorhast.

Was ich aber sehe, kommt mir ein wenig komisch vor. Du hast ein Object vom Typ A und rufst darauf einen Call von .toArray aus um aus einem A ein A[] zu machen?!
 
Genau.
Ich will einer C-DLL ein Array übergeben, dass die DLL dann mit Leben füllt.
Das Array muss kontinuierlich im Speicher liegen, deswegen das "toArray()".
Oder gibt es dazu eine Alternative, die weniger resourcenhungrig ist und schneller funktioniert?
Viel mehr als das was ich oben geschrieben habe, ist in meinem Java-Code nicht drin.
Danach kommt nur noch der DLL-Aufruf, davor nur das Einbinden der DLL selbst.
 
Vielleicht war meine Frage nicht deutlich genug vermuliert...
Du hast ein einzelnes Objekt und willst aus diesem einen Objekt plötzlich ein Array vom Typ dieses Objektes machen. Was soll denn dabei herauskommen?

Oder anders ausgedrückt: Einen Sack voll Kartoffeln kann man umpacken in eine Kartoffelkiste. Aber was soll es bedeuten, wenn du aus einer einzelnen Kartoffel eine Kartoffelkiste machen willst? 🙂
 
Ziemlich genauso hatte ich das in einem Beispiel gefunden.
Und wenn ich im toArray() weniger Elemente angebe(z.B 50 statt 500), dann funktioniert das ja auch.
Ich erhalte dann ein Array "AudioStatistics[0..49]" das kontinuierlich im Speicher liegt.

Mein erster Ansatz war:
Java:
  sAudioStatistics[] AudioStatistics = new sAudioStatistics[50];
  for (i=0; i<50; i++)
  {	
    AudioStatistics[i] = new sAudioStatistics();
    AudioStatistics[i].Peaks[i] = new sPeaks();
  }

aber die Elemete liegen nicht speicherkontinuierlich.

Wie würdest du denn ein entsprechenden Array erzeugen?

Grüße,
Uwe
 

Neue Themen


Zurück
Oben