Java ruft automatisch den Garbage Collector auf, warum brauchen wir also manuelle Aufrufe für die Müllsammlung? Wann sollte System.gc() verwendet werden?
Antworten
Zu viele Anzeigen?Java ruft den Garbage Collector automatisch auf, warum brauchen wir dann manuelle Aufrufe für die Müllsammlung?
Wir brauchen sie nicht. Tatsächlich ist es in den meisten Fällen schädlich für die Anwendungsleistung, System.gc()
aufzurufen. Siehe meine Antwort auf "Warum ist es eine schlechte Praxis, den System-GC aufzurufen" für eine detaillierte Erklärung.
Wann sollte man System.gc() verwenden
Wenn die Anwendung weiß, dass sie in eine Phase geht, in der sie nichts anderes zu tun hat UND der Benutzer unwahrscheinlich ist, eine Müllsammlung zu bemerken, dann ist es vielleicht in Ordnung, System.gc()
aufzurufen, um sicherzustellen, dass der Benutzer keine GC-Pausen in der Zukunft erlebt.
Die Nachteile sind:
- Das Aufrufen von
System.gc()
ruft in der Regel einen vollständigen GC auf, der wesentlich länger dauert als ein GC des "neuen Speicherbereichs". - Der Benutzer könnte tatsächlich darauf achten / bemerken. Zum Beispiel, wenn Sie
System.gc()
zwischen "Levels" in einem Spiel aufrufen, dauert das Laden des nächsten Levels länger. - Indem Sie den GC erzwingen, veranlassen Sie die JVM dazu, zusätzliche CPU-Zyklen usw. zu nutzen, was möglicherweise mit anderen Dingen interferieren könnte, die der Benutzer auf seinem Rechner macht.
(Es gibt auch legitime Gründe, System.gc()
in Unit-Tests und während der Systemdebugging aufzurufen.)
Es besteht kein Bedarf, explizit eine Garbage Collection anzufordern, und das Aufrufen von System.gc()
ist nur ein Vorschlag, den die JVM ignorieren kann.
Die einzigen praktischen Verwendungen, die mir einfallen, sind
- Während der Fehlersuche kann das Erzwingen einer Sammlung einen Speicherleck aufdecken
- Wenn das Programm vorhersehbare Zyklen intensiver Berechnungen durchläuft, gefolgt von keinen Berechnungen (wie bei einem rundenbasierten Spiel), könnte die CPU während des Zeitraums ohne Berechnungen für eine vorgeschlagene Garbage Collection genutzt werden, um ein Ruckeln während der intensiven Berechnungsabschnitte zu verhindern.
System.gc() ist nur ein Vorschlag. Aber es macht in einigen Situationen Sinn.
Angenommen, Sie haben die Klasse MyClass und fragen sich, wie viel Speicherplatz eine Instanz einnimmt. Was Sie tun können, ist dies (großzügig gesagt):
MyClass [] objects= new MyClass[100000];
System.gc();
long memoryNow = Runtime.getRuntime().freeMemory();
for (int i = 0; i < 100000; i ++) {
objects[i] = new MyClass();
}
System.gc();
long memoryLater = Runtime.getRuntime().freeMemory();
int objectSize = (int)((memoryLater - memoryNow) / 100000);
Es gibt andere ähnliche Fälle, in denen ich System.gc() nützlich gefunden habe.
Der Garbage Collector wird immer von der JVM aufgerufen, wenn nicht genügend Speicher vorhanden ist, um neue Objekte im Heap zuzuweisen. Beim Aufrufen des Garbage Collectors folgt er den Normen von Stop the World und ruft dafür die System.gc()
Methode auf.
Vergiss auch nicht, dass die JVM auch parallel gc-Threads ausführt, um ungenutzte Objekte aus dem Speicher zu entfernen. So überwacht die JVM ständig den Heap-Speicher und versucht immer, ihn nicht zu überlasten. Daher besteht keine Notwendigkeit, die System.gc()
oder Runtime.gc()
Methode explizit aufzurufen.
Wenn Sie weitere Details dazu wünschen, können Sie hier relevante Informationen erhalten.
Ein noch nicht erwähnter Aspekt ist, dass bestimmte Arten von Objekten Entitäten außerhalb von sich selbst bitten können, Dinge in ihrem Namen zu tun (z.B. ihnen exklusiven Zugriff auf eine nicht fungible Ressource wie eine Datei zu gewähren), zum Nachteil anderer Entitäten. Wenn ein Garbage-Collection durchgeführt wird, wird das System nicht nur Speicher freigeben, der zuvor von unerreichbaren Objekten belegt war, sondern es wird auch finalize
auf Objekten aufrufen, die es verlassen sieht, und somit ermöglichen, dass solche Objekte Entitäten außerhalb informieren, dass ihre Dienste nicht mehr benötigt werden. Es ist durchaus möglich, dass ein Programm einen Zustand erreicht, in dem genügend Speicher vorhanden ist, aber eine notwendige Ressource nicht verfügbar ist, weil einem Objekt exklusiver Zugriff gewährt wurde und es seitdem verlassen wurde, ohne ihn freizugeben. Das erzwingen des Garbage-Collectors in einer solchen Situation kann manchmal die notwendige Ressource freigeben.
- See previous answers
- Weitere Antworten anzeigen