Wann zu Garbage Collect

8

Ich habe einen Code, der ein sehr großes Bild in den Speicher lädt. Es schien also vernünftig zu sein,

zu nennen %Vor%

vor dem Laden des Bildes. Von dem, was ich sagen kann, funktioniert es ohne Probleme.

Gestern habe ich mich entschieden, eine ziemlich nützliche Software namens FindBugs zu verwenden, die Ihren Code scannt und Probleme meldet, die Fehler verursachen könnten allgemein nicht empfohlene Strategien. Das Problem ist, dass dieser Code, den ich erwähnt habe, gemeldet wird. Die Beschreibung ist dies:

  

... erzwingt die Müllsammlung;   äußerst zweifelhaft außer in   Benchmarking-Code

Und es geht weiter:

  

Code ruft explizit Müll auf   Sammlung. Außer für spezifische Verwendung in   Benchmarking ist das sehr zweifelhaft.

     

In der Vergangenheit, Situationen, in denen Menschen   habe explizit den Müll aufgerufen   collector in Routinen wie Schließen oder   finalize Methoden hat zu riesigen geführt   Leistung schwarze Löcher. Müll   Sammlung kann teuer sein. Irgendein   Situation, die Hunderte zwingt   Tausende von Müllsammlungen werden   Bring die Maschine zum Kriechen.

Also meine Frage ist: Ist es nicht OK, den Garbage Collector in einem solchen Fall programmgesteuert aufzurufen? Mein Code ruft es nur einmal auf und die Methode, in der es sich befindet, wird selten verwendet. Und wenn es nicht OK ist, es anzurufen, was sollten Sie in einem Fall tun, in dem Sie so viel Speicher wie möglich benötigen, bevor Sie eine sehr speicherintensive Operation ausführen und vorher so viel Speicher wie möglich freigeben müssen?

    
Savvas Dalkitsis 18.07.2009, 12:10
quelle

8 Antworten

9

Hast du irgendwelche Leistungsverbesserungen mit System.gc () bekommen? Ich denke nicht, da Sie wahrscheinlich nicht viele Objekte gesammelt haben, bevor Sie das Bild laden.

Normalerweise wissen moderne Müllsammler am besten, wann sie laufen sollen, also sollten Sie keine Sammlung erzwingen, es sei denn, Sie haben einen wirklich guten Grund dafür. (zum Beispiel eine Benchmarking-Anwendung wie von diesem Plugin vorgeschlagen)

btw: Aufruf von System.gc () empfiehlt der VM, eine "vollständige" oder "große" Sammlung durchzuführen, was bedeutet, dass alle Threads in Kürze gestoppt werden. Sonst wird es wahrscheinlich nur "kleine" Garbage Collections geben, die nicht alle Threads stoppen.

Führen Sie Ihr Programm mit -verbose: gc aus, um zu sehen, wie viele Bytes gesammelt wurden.

Hier finden Sie auch viele technische Informationen zur Müllabfuhr: Ссылка

    
clamp 18.07.2009, 12:18
quelle
9

In der Regel ist der GC schlauer als Sie, daher sollten Sie ihn immer ausführen, wenn die Laufzeit entscheidet. Wenn die Laufzeit Speicher benötigt, wird der GC selbst ausgeführt

    
nos 18.07.2009 12:17
quelle
1

Es ist in Ordnung, den Garbage Collector aufzurufen, Sie bekommen davon keine "Probleme". Ich bezweifle jedoch, dass dies die Leistung erheblich steigern wird, es sei denn, dieser Aufruf befasst sich auch mit der Defragmentierung der zugewiesenen Daten. Das weiß ich nicht.

In diesem Fall sollten Sie den Code profilieren. Führen Sie es mehrmals aus, um zu sehen, welche Art von Ergebnissen Sie erhalten.

    
Daniel Goldberg 18.07.2009 12:14
quelle
1

Normalerweise sollten Sie den Garbage Collector nicht stören. Wenn es notwendig ist, etwas Speicher freizugeben, bevor das Bild geladen wird, dann erledigt der Garbage Collector das für Sie.

Egal, ob du es nur einmal tust, es wird deine Leistung wahrscheinlich nicht drastisch beeinflussen. Dinge in Schleifen sind viel wichtiger.

    
Donnie DeBoer 18.07.2009 12:17
quelle
1

Sie haben bereits viele gute Ratschläge erhalten, die ich nicht wiederholen werde.

Wenn Sie tatsächlich Probleme mit dem GC haben, wie zum Beispiel die Punkte Ihrer Bewerbung für eine Sekunde, gehen Sie folgendermaßen vor: 1. Überprüfen Sie, ob keine Aufrufe von System.gc () vorhanden sind. 2. Überprüfen Sie die verschiedenen Optionen zum Konfigurieren des GC. Es gibt Tonnen von denen in der Nähe, und sie sind viel hilfreicher, dann zwingen GC.

    
Jens Schauder 18.07.2009 12:30
quelle
1

Stellen Sie sicher, dass die großen Objekte so früh wie möglich aktiviert werden können. I.e. setze Variablen auf null und / oder lasse sie außerhalb des Gültigkeitsbereichs fallen. Das hilft!

    
quelle
1

Wenn eine Speicherzuordnung fehlschlägt, wird ein GC-Zyklus initiiert und die Zuweisung wird erneut versucht.

    
clemahieu 18.07.2009 17:36
quelle
0

Im Allgemeinen, nein. Es ist nicht angemessen, System.gc () aufzurufen. Ich hatte jedoch einige Fälle, in denen es Sinn machte.

In der Software, die ich schreibe, gibt es eine integrierte Performance-Tracking-Ebene. Es wird hauptsächlich während des automatisierten Tests verwendet, kann aber im Feld für diagnostische Zwecke verwendet werden. Zwischen den Tests oder nach bestimmten Durchläufen werden wir System.gc einige Male aufrufen und dann den noch vorhandenen Speicher aufzeichnen. Es liefert uns einen grundlegenden Speicher-Footprint-Benchmark, um Speicherverbrauchs-Trendlinien im Zeitverlauf zu beobachten. Während dies mit einigen der externen JVM-Schnittstellen getan werden kann, war es einfacher, dies an Ort und Stelle zu tun, und genaue Zahlen waren nicht erforderlich.

Auf einem viel älteren System könnten wir mehr als 72 separate JVMs haben (ja, 72, es gab einen guten Grund dafür zum Zeitpunkt der Konstruktion). Wenn in diesem System der Heap auf allen 72 JVMs frei float gelassen wird, könnte dies zu einem übermäßigen Speicherverbrauch führen (weit über den physischen Speicher hinaus). System.gc () wurde zwischen schweren Datenübungen aufgerufen, um zu versuchen, die JVM näher am Durchschnitt zu halten, damit der Heap nicht wächst (das Hacken hätte eine andere Richtung sein können, aber dann hätte es die Implementierer erforderlich gemacht, mehr pro Site zu konfigurieren und mehr bewusst sein, was unter der Haube geschah, um es richtig zu machen und das System nicht unter Last versagen zu lassen).

    
Jim Rush 18.07.2009 14:21
quelle