T
tuxedo
Gast
Liest jmd. von euch regelmäßig den "The Java(tm) Specialist Newsletter"?
Da gabs gestern eine neue Ausgabe von mit einem recht "coolen" Puzzle:
Diese Source führt unweigerlich zu einer OutOfMemoryException. Wieso? Gute Frage. Eigentlich müsste die data Variable nur in ihrem eigene Scope leben vom GC rechtzeitig, bevor data2 allokiert wird, wieder abgeräumt werden. Fakt ist aber das dem in diesem Sample nicht so ist.
Diese Code hingegen läuft problemlos. Ich hab mich da auch mal dran versucht und ein wenig gebastelt. Scheinbar reicht ein winzig kleines Codefragment zwischen den zwei byte[] Allokationen aus damit der GC aufräumt.
Die Frage die sich jetzt stellt: Wieso und warum ist das so?
Meine Antwort die ich eingeschickt hatte war: Der GC läuft in einem asynchronen Thread im Hintergrund und hat im ersten Beispiel einfach keine Zeit aufzuräumen. Im zweiten Beispiel hingegen reicht es um den GC zu triggern, so dass aufgeräumt wird.
Zweite Vermutung: Das allokieren hat gegenüber dem aufräumen eine höhere Prio in der JVM.
Beide Möglichkeiten wurdem vom Newsletterauto Heinz als falsch abgelehnt.
Ist hier jemand so schlau und findet die Lösung?
- Alex
Da gabs gestern eine neue Ausgabe von mit einem recht "coolen" Puzzle:
Java:
public class JavaMemoryPuzzle {
private final int dataSize =
(int) (Runtime.getRuntime().maxMemory() * 0.6);
public void f() {
{
byte[] data = new byte[dataSize];
}
byte[] data2 = new byte[dataSize];
}
public static void main(String[] args) {
JavaMemoryPuzzle jmp = new JavaMemoryPuzzle();
jmp.f();
}
}
Diese Source führt unweigerlich zu einer OutOfMemoryException. Wieso? Gute Frage. Eigentlich müsste die data Variable nur in ihrem eigene Scope leben vom GC rechtzeitig, bevor data2 allokiert wird, wieder abgeräumt werden. Fakt ist aber das dem in diesem Sample nicht so ist.
Java:
public class JavaMemoryPuzzlePolite {
private final int dataSize =
(int) (Runtime.getRuntime().maxMemory() * 0.6);
public void f() {
{
byte[] data = new byte[dataSize];
}
for(int i=0; i<10; i++) {
System.out.println("Please be so kind and release memory");
}
byte[] data2 = new byte[dataSize];
}
public static void main(String[] args) {
JavaMemoryPuzzlePolite jmp = new JavaMemoryPuzzlePolite();
jmp.f();
System.out.println("No OutOfMemoryError");
}
}
Diese Code hingegen läuft problemlos. Ich hab mich da auch mal dran versucht und ein wenig gebastelt. Scheinbar reicht ein winzig kleines Codefragment zwischen den zwei byte[] Allokationen aus damit der GC aufräumt.
Die Frage die sich jetzt stellt: Wieso und warum ist das so?
Meine Antwort die ich eingeschickt hatte war: Der GC läuft in einem asynchronen Thread im Hintergrund und hat im ersten Beispiel einfach keine Zeit aufzuräumen. Im zweiten Beispiel hingegen reicht es um den GC zu triggern, so dass aufgeräumt wird.
Zweite Vermutung: Das allokieren hat gegenüber dem aufräumen eine höhere Prio in der JVM.
Beide Möglichkeiten wurdem vom Newsletterauto Heinz als falsch abgelehnt.
Ist hier jemand so schlau und findet die Lösung?
- Alex