Wenn Java Garbage Collection aufweist, warum tritt OutOfMemoryError dann auf? [Duplikat]

7

Dies ist eine theoretische Frage. Ich bin nur Kuriositäten, dass, wenn Java einen Mechanismus für Garbage Collection hat, um den Speicher zu befreien, warum immer noch OutOfMemoryError auftreten?

Ich habe nach SO gesucht, konnte aber diese Links erhalten

Ist der Müllsammler garantiert? vor einem Fehler wegen zu wenig Speicher ausgeführt werden?

Garbage Collection vor OutOfMemoryError

Diese beantworten meine Frage nicht speziell. Wenn Java Speicher so gut durch Garbage Collection ermöglicht, warum tritt OutOfMemoryError dann auf?

    
Prasad Kharkar 25.06.2013, 02:19
quelle

7 Antworten

12

Ein OutOfMemoryError kann auftreten, wenn keines der Objekte im Speicher für die Garbage Collection geeignet ist. Zum Beispiel:

%Vor%

Dies erstellt eine Liste und fügt MyClass Objekte hinzu, bis der Speicher aufgebraucht ist. Keines der Objekte ist für die Garbage Collection geeignet, da es Referenzen auf alle Objekte gibt.

    
Code-Apprentice 25.06.2013, 02:25
quelle
3

Es ist auch möglich, den Speicher auf eine Weise zu maskieren, die Sie nicht erwarten. Betrachten Sie das folgende String-Beispiel.

%Vor%

Das Array chars kann gesammelt werden. Das Array in string wird möglicherweise nicht erfasst, da substring einen Verweis auf das interne Array gefolgt von einem Offset und einem Bereich enthält. Somit bleiben 10 7 Zeichen zugeordnet, obwohl nur 5 * 10 6 verwendet und zugänglich sind.

Java 1.7.0_06

Anscheinend hat String.substring dieses Verhalten nicht mehr. In einem Artikel in der Java Performance Tuning Guide-Website berichtet Mikhail Vorontsov das in Java 1.7.0_06 und höher, String.substring erstellt immer ein neues String unabhängig von dem alten. Die String -Klasse hat nicht mehr offset und range Instanzvariablen. Wenn Sie eine große Zeichenfolge erstellen, Teilzeichenfolgen verwenden und das Original wegwerfen, wird die char[] der alten Zeichenfolge nicht entfernt.

%Vor%     
Eric Jablow 25.06.2013 02:43
quelle
2

Weil nicht jeder Speicher Müll ist.

    
EJP 25.06.2013 02:55
quelle
1

Garbage Collector arbeitet mit Speicher, der nicht verwendet wird.

Wenn Sie jedoch Speicher zuweisen und der Speicher im Bereich ist, bedeutet dies, dass der Garbage Collector diesen Speicher nicht wirklich bereinigen kann.

Wenn der zugewiesene Speicher zu hoch über dem für die VM zulässigen liegt, erhalten Sie diese Ausnahme.

    
mrcaramori 25.06.2013 02:23
quelle
1

Ein Objekt, das immer noch einen Verweis auf den Code enthält, kann nicht gesammelt werden. Wenn es also einen Weg gibt, theoretisch auf ein Objekt zuzugreifen, bleibt es im Speicher stecken.

Nur so heißt es, Java beseitigt nicht die Notwendigkeit, sich um das Gedächtnis zu kümmern; Es automatisiert nur eine Menge Speicherverwaltung. Du musst immer noch deinen Teil dazu beitragen, dass du keine Objekte wegwirfst, nachdem ihr nützliches Leben vorbei ist ... denn solange sie (indirekt) erreicht werden können, nehmen sie Speicher auf, der nicht zurückgewonnen werden kann .

    
cHao 25.06.2013 02:24
quelle
0

Es ist besser, Ihre Objekte zu annullieren, sobald Ihre Arbeit mit ihnen abgeschlossen wurde, damit Sie sicherstellen können, dass die Objekte dem Garbage Collector zur Verfügung stehen, um die Probleme bezüglich Speichermangel oder Speicherverlust zu vermeiden.

    
Annaji 25.06.2013 02:50
quelle
0

Wenn Sie keinen Speicher mehr haben und keine Variable oder kein Objekt zum Entfernen verfügbar ist, wird die Ausnahme ausgelöst.

Der beste Weg also, GC (Garbage Collection) zu verwenden, ist:

Ordnen Sie die Variable explizit dem Nullwert zu, wenn sie nicht mehr verwendet wird.

    
Keane_zhou 25.06.2013 02:53
quelle