Defragmentierung der Java-Speicherbereinigung

9

Ich erhalte eine OutOfMemoryError-Java-Heap-Ausnahme, wenn ich nur ein Byte-Array zuordne und freigebe, obwohl genügend freier Speicher für die Zuweisung vorhanden ist. Es gibt ein kurzes Protokoll unten. Ich weiß von einer anderen JVM, dass das Problem auf fragmentierten Speicher zurückzuführen ist und dass der größte freie Block nur etwa 6 MB groß ist. Ich dachte, dass die Java (Orakel) JVM für fragmentierten Speicher sorgen sollte.

Das ist mein Test:

  • Richten Sie die Java-JVM mit params -Xms10M -Xmx10M
  • ein
  • Ich weise ein Byte-Array von etwa 90 Prozent des JVM-Speichers zu.
  • Setzen Sie dieses Byte-Array dann auf null und versuchen Sie dann, das Byte-Array mit 90 Prozent des JVM-Speichers neu zuzuweisen.
  • Wir sehen aus den Protokollen, dass der JVM-Speicher auf den vollen Betrag zurückgesetzt wurde, aber wir können nicht dieselbe Speichermenge zuweisen.
  • Also muss das Gedächtnis fragmentiert sein?

Hier sind meine Details:

%Vor%

Die andere JVM, die ich betreibe, ist CEE-J von Skelmir. Ich laufe auf einem Low-Memory-Gerät, so dass ich die MaxPermSize nicht einstellen kann. Es ist interessant, dass der Java-Heap in verschiedene Bereiche aufgeteilt wird, können diese Bereiche die Größe nach der Garbage Collection ändern? Ich habe einen anderen Test ausgeführt, bei dem ich Erstellen Sie zuerst ein Byte-Array für etwa 95 Prozent des Speichers, dann geben Sie das Array wieder frei, dann erstelle ich eine Ladung von Arrays von Objekten, die hashmaps mit jeweils einem Eintrag enthalten, Ich lösche das Array und die Maps und ordne die Arrays dann erneut zu.

Ich überprüfe den Speicher bei jeder Zuweisung und Freigabe. Nachdem du das getan hast, sage 10 Mal, ich befreie die Erinnerung zum letzten Mal, Dann überprüfe ich den Speicher, sehe, dass ich die volle JVM-Zuweisung habe, Ich versuche dann, die 95% der JVM-Zuweisung erneut zuzuweisen und die gleiche JVM-Ausnahme für nicht genügend Arbeitsspeicher zu erhalten, obwohl es besagt, dass ich genug Speicher für die Zuweisung habe?

%Vor%

Ausgabeprotokoll aus dem zweiten Test. Gesamter freier Speicher: 9881728 Versuch, Array der Größe 6917209 zuzuordnen Freigebende Array der Größe: 6917209 Verwendeter Speicher: 7519744 -Iteration: 0, um Speicher freizugeben -Iteration: 0 um Speicher neu zuzuweisen -verwendeter Speicher: 7890928 -Max Speicher: 10092544 -Freier Speicher: 2147808 -Iteration: 1 über die Freigabe von Memory - Iteration: 1 um Speicher neu zuzuweisen -verwendeter Speicher: 930952 -Max Speicher: 10092544 -Freier Speicher: 9107792 - Iteration: 2 kurz davor, Memory freizugeben -Iteration: 2 um Speicher neu zuzuweisen -verwendeter Speicher: 1181832 -Max Speicher: 10092544 -Freier Speicher: 8856912 -Iteration: 3 über die Freigabe von Memory - Iteration: 3 um Speicher neu zuzuweisen -verwendeter Speicher: 1190552 -Max Speicher: 10092544 -Freier Speicher: 8848192 -Iteration: 4 kurz vor der Veröffentlichung von Memory - Iteration: 4 um Speicher neu zuzuweisen -verwendeter Speicher: 902408 -Max Speicher: 10092544 -Freier Speicher: 9190136 -Iteration: 5 im Begriff, Speicher freizugeben -Iteration: 5 um Speicher neu zuzuweisen -verwendeter Speicher: 902408 -Max Speicher: 10092544 -Freier Speicher: 9190136 -Iteration: 6 kurz vor der Veröffentlichung von Memory -Iteration: 6 um Speicher neu zuzuweisen -verwendeter Speicher: 902408 -Max Speicher: 10092544 -Freier Speicher: 9190136 -Iteration: 7 kurz vor der Veröffentlichung von Memory -Iteration: 7 um Speicher neu zuzuweisen -verwendeter Speicher: 902408 -Max Speicher: 10092544 -Freier Speicher: 9190136 - Iteration: 8 wird den Speicher freigeben -Iteration: 8 um Speicher neu zuzuweisen -verwendeter Speicher: 902408 -Max Speicher: 10092544 -Freier Speicher: 9190136 -Iteration: 9 im Begriff, Speicher freizugeben -Iteration: 9 um Speicher neu zuzuweisen -verwendeter Speicher: 902408 -Max Speicher: 10092544 -Freier Speicher: 9190136 Die Arrays zum letzten Mal freigeben Versuch, Array der Größe 6917209 zuzuordnen Gesamter freier Speicher: 9956688 Ausnahme im Thread "main" java.lang.OutOfMemoryError: Java-Heap-Space

    
madlad 29.09.2011, 08:34
quelle

3 Antworten

3

Der Java-Heap ist in mehrere Bereiche aufgeteilt. Eine einzelne Zuweisung kann keine Bereiche umfassen. Es gibt verschiedene -XX -Optionen in der Oracle JRE [Ich lasse etwas anderes auf die Details verweisen], die die Konfiguration von Zuweisungen erlauben. Sie könnten die Eden- und Survivor-Bereiche sehr klein einstellen. Ein weiteres Problem, wenn nach einer Sammlung nicht genügend Speicher verfügbar ist, erhalten Sie möglicherweise immer noch ein OOME, um das Thrashing zu verhindern (wiederum mehr Optionen -XX , um dies zu kontrollieren).

    
Tom Hawtin - tackline 29.09.2011 09:02
quelle
1

Fügen Sie -XX: MaxPermSize-Argument hinzu, um Heap ausreichend Platz zu geben.

%Vor%     
prageeth 29.09.2011 09:06
quelle
0

In welcher anderen JVM haben Sie Ihr Programm erfolgreich ausgeführt? Wenn Sie von IBM jdk sprechen, ist die Heap-Verwaltung völlig anders als die Sun (Oracle) jvm-Heap-Verwaltung. Ссылка

    
Nikesh PL 29.09.2011 10:00
quelle

Tags und Links