Normalerweise nein.
Aber wie alle Dinge: es kommt darauf an. Der GC in Java ist heutzutage SEHR gut und alles sollte sehr kurz nach seiner Erreichbarkeit bereinigt werden. Dies erfolgt unmittelbar nach dem Verlassen einer Methode für lokale Variablen und wenn auf eine Klasseninstanz für Felder nicht mehr verwiesen wird.
Sie müssen nur explizit null setzen, wenn Sie wissen, dass ansonsten darauf verwiesen wird. Zum Beispiel ein Array, das herumgehalten wird. Möglicherweise möchten Sie die einzelnen Elemente des Arrays auf Null setzen, wenn sie nicht mehr benötigt werden.
Beispiel: Dieser Code aus ArrayList:
public E remove(int index) {
RangeCheck(index);
modCount++;
E oldValue = (E) elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
return oldValue;
}
Wenn Sie ein Objekt explizit auf Null setzen, wird ein Objekt nicht früher erfasst, als wenn es auf natürliche Weise den Gültigkeitsbereich verlassen hätte, solange keine Referenzen mehr vorhanden sind.
Beide:
void foo() {
Object o = new Object();
/// do stuff with o
}
und:
void foo() {
Object o = new Object();
/// do stuff with o
o = null;
}
Sind funktional gleichwertig.
System.gc()
, wird sie entfernt (vorausgesetzt, es gibt keine anderen Verweise, die auf dieses Objekt verweisen).Nach meiner Erfahrung heben die Leute häufig Referenzen aus Paranoia auf, nicht aus Notwendigkeit. Hier ist eine kurze Richtlinie:
Wenn Objekt A auf Objekt B verweist und Sie diese Referenz nicht mehr benötigen und Objekt A nicht für die Speicherbereinigung berechtigt ist, sollten Sie das Feld explizit auf Null setzen. Es ist nicht erforderlich, ein Feld auf Null zu setzen, wenn für das einschließende Objekt ohnehin Müll gesammelt wird. Das Nullstellen von Feldern in einer dispose () -Methode ist fast immer nutzlos.
In einer Methode erstellte Objektreferenzen müssen nicht auf Null gesetzt werden. Sie werden automatisch gelöscht, sobald die Methode beendet wird. Die Ausnahme von dieser Regel besteht darin, dass Sie in einer sehr langen Methode oder einer massiven Schleife ausgeführt werden und sicherstellen müssen, dass einige Referenzen vor dem Ende der Methode gelöscht werden. Auch diese Fälle sind äußerst selten.
Ich würde sagen, dass Sie die meiste Zeit keine Referenzen auf Null setzen müssen. Der Versuch, den Garbage Collector auszutricksen, ist nutzlos. Sie erhalten nur ineffizienten, unlesbaren Code.
quelle
Guter Artikel ist der heutige Coding-Horror .
Die Arbeit von GC besteht darin, nach Objekten zu suchen, die keine Zeiger auf sie haben. Der Bereich ihrer Suche ist Heap / Stack und alle anderen Leerzeichen, die sie haben. Wenn Sie also eine Variable auf null setzen, wird das tatsächliche Objekt jetzt von niemandem mehr angezeigt und kann daher als GC bezeichnet werden.
Da der GC jedoch möglicherweise nicht genau zu diesem Zeitpunkt ausgeführt wird, kaufen Sie sich möglicherweise selbst nichts. Wenn Ihre Methode jedoch ziemlich lang ist (in Bezug auf die Ausführungszeit), lohnt es sich möglicherweise, da Sie Ihre Chancen erhöhen, dass GC dieses Objekt sammelt.
Das Problem kann auch bei Codeoptimierungen kompliziert sein. Wenn Sie die Variable nie verwenden, nachdem Sie sie auf null gesetzt haben, ist es eine sichere Optimierung, die Zeile zu entfernen, in der der Wert auf null gesetzt wird (eine auszuführende Anweisung weniger). Sie erhalten also möglicherweise keine Verbesserung.
Zusammenfassend kann es also helfen, aber es wird nicht deterministisch sein .
quelle
Zumindest in Java ist es überhaupt keine Voodoo-Programmierung. Wenn Sie ein Objekt in Java mit so etwas wie erstellen
Sie machen zwei Dinge: Erstens erstellen Sie einen Verweis auf ein Objekt und zweitens erstellen Sie das Foo-Objekt selbst. Solange diese oder eine andere Referenz existiert, kann das spezifische Objekt nicht gc'd werden. Wenn Sie dieser Referenz jedoch null zuweisen ...
und vorausgesetzt, nichts anderes hat einen Verweis auf das Objekt, ist es freigegeben und für gc verfügbar, wenn der Garbage Collector das nächste Mal vorbeikommt.
quelle
Es hängt davon ab, ob.
Im Allgemeinen halten Sie Verweise auf Ihre Objekte kürzer, je schneller sie gesammelt werden.
Wenn die Ausführung Ihrer Methode beispielsweise 2 Sekunden dauert und Sie nach einer Sekunde der Methodenausführung kein Objekt mehr benötigen, ist es sinnvoll, alle Verweise darauf zu löschen. Wenn GC nach einer Sekunde feststellt, dass auf Ihr Objekt immer noch verwiesen wird, wird es beim nächsten Mal möglicherweise in etwa einer Minute überprüft.
Jedenfalls ist es für mich eine vorzeitige Optimierung, alle Verweise standardmäßig auf Null zu setzen, und niemand sollte dies tun, es sei denn, in bestimmten seltenen Fällen wird der Speicherverbrauch messbar verringert.
quelle
Das explizite Festlegen eines Verweises auf null, anstatt nur die Variable aus dem Gültigkeitsbereich zu entfernen, hilft dem Garbage Collector nicht, es sei denn, das gehaltene Objekt ist sehr groß. Es ist eine gute Idee, es auf null zu setzen, sobald Sie damit fertig sind.
Wenn Sie Verweise im Allgemeinen auf null setzen, bedeutet dies für den LESER des Codes, mit dem dieses Objekt vollständig fertig ist, und sollte sich nicht mehr darum kümmern.
Ein ähnlicher Effekt kann erzielt werden, indem ein engerer Bereich eingeführt wird, indem ein zusätzlicher Satz Zahnspangen eingesetzt wird
Auf diese Weise kann das bigThing direkt nach dem Verlassen der verschachtelten Klammern als Müll gesammelt werden.
quelle
Über Programm wirft
OutOfMemoryError
. Wenn Sie auskommentierendata = null;
,OutOfMemoryError
ist das gelöst. Es wird immer empfohlen, die nicht verwendete Variable auf null zu setzenquelle
Ich habe einmal an einer Videokonferenzanwendung gearbeitet und einen großen Leistungsunterschied festgestellt, als ich mir die Zeit nahm, Referenzen auf Null zu setzen, sobald ich das Objekt nicht mehr brauchte. Dies war in den Jahren 2003-2004 und ich kann mir nur vorstellen, dass der GC seitdem noch schlauer geworden ist. In meinem Fall kamen und gingen jede Sekunde Hunderte von Objekten aus dem Geltungsbereich, sodass ich den GC bemerkte, als er regelmäßig einschaltete. Nachdem ich jedoch darauf hingewiesen hatte, Objekte auf Null zu setzen, hörte der GC auf, meine Anwendung anzuhalten.
Es kommt also darauf an, was du tust ...
quelle
Ja.
Aus "The Pragmatic Programmer" S.292:
Indem Sie einen Verweis auf NULL setzen, reduzieren Sie die Anzahl der Zeiger auf das Objekt um eins ... (wodurch der Garbage Collector es entfernen kann).
quelle
Ich gehe davon aus, dass sich das OP auf solche Dinge bezieht:
Würde die VM sie in diesem Fall nicht für GC markieren, sobald sie den Gültigkeitsbereich verlassen?
Oder würde aus einer anderen Perspektive das explizite Setzen der Elemente auf Null dazu führen, dass sie eine GC-Prüfung erhalten, bevor sie dies tun würden, wenn sie nur den Gültigkeitsbereich verlassen würden? In diesem Fall verbringt die VM möglicherweise Zeit mit der GC-Prüfung des Objekts, wenn der Speicher ohnehin nicht benötigt wird. Dies würde tatsächlich zu einer schlechteren CPU-Auslastung führen, da die GC früher ausgeführt wird.
quelle
null
das GC-Verhalten überhaupt beeinflusst." Es kommt darauf an "
Ich kenne Java nicht, aber in .net (C #, VB.net ...) ist es normalerweise nicht erforderlich, eine Null zuzuweisen, wenn Sie kein Objekt mehr benötigen.
Beachten Sie jedoch, dass dies "normalerweise nicht erforderlich" ist.
Durch die Analyse Ihres Codes bewertet der .net-Compiler die Lebensdauer der Variablen gut ... um genau zu erkennen, wann das Objekt nicht mehr verwendet wird. Wenn Sie also obj = null schreiben, sieht es möglicherweise so aus, als ob das obj noch verwendet wird. In diesem Fall ist es kontraproduktiv, eine Null zuzuweisen.
Es gibt einige Fälle, in denen es tatsächlich hilfreich sein kann, eine Null zuzuweisen. Ein Beispiel ist, dass Sie einen riesigen Code haben, der lange ausgeführt wird, oder eine Methode, die in einem anderen Thread oder einer Schleife ausgeführt wird. In solchen Fällen kann es hilfreich sein, null zuzuweisen, damit der GC leicht erkennen kann, dass er nicht mehr verwendet wird.
Hierfür gibt es keine feste Regel. Gehen Sie an der obigen Stelle vorbei und weisen Sie Ihrem Code Null-Zuweisungen zu. Führen Sie einen Profiler aus, um festzustellen, ob dies in irgendeiner Weise hilfreich ist. Höchstwahrscheinlich sehen Sie keinen Nutzen.
Wenn es sich um .net-Code handelt, den Sie optimieren möchten, ist es meiner Erfahrung nach vorteilhafter, mit Dispose- und Finalize-Methoden vorsichtig umzugehen, als sich um Nullen zu kümmern.
Einige Referenzen zum Thema:
http://blogs.msdn.com/csharpfaq/archive/2004/03/26/97229.aspx
http://weblogs.asp.net/pwilson/archive/2004/02/20/77422.aspx
quelle
Selbst wenn das Aufheben der Referenz geringfügig effizienter wäre, wäre es die Hässlichkeit wert, Ihren Code mit diesen hässlichen Aufhebungen pfeffern zu müssen? Sie wären nur unübersichtlich und verdecken den Intent-Code, der sie enthält.
Es ist eine seltene Codebasis, die keinen besseren Kandidaten für eine Optimierung hat als den Versuch, den Garbage Collector auszutricksen (noch seltener sind Entwickler, denen es gelingt, ihn auszutricksen). Ihre Bemühungen werden höchstwahrscheinlich besser woanders eingesetzt, indem Sie diesen mürrischen XML-Parser fallen lassen oder eine Gelegenheit finden, die Berechnung zwischenzuspeichern. Diese Optimierungen sind einfacher zu quantifizieren und erfordern nicht, dass Sie Ihre Codebasis mit Rauschen verschmutzen.
quelle
Bei der zukünftigen Ausführung Ihres Programms werden die Werte einiger Datenelemente verwendet, um eine außerhalb des Programms sichtbare Ausgabe zu berechnen. Andere können verwendet werden oder nicht, abhängig von zukünftigen (und nicht vorhersehbaren) Eingaben in das Programm. Andere Datenelemente werden möglicherweise nicht verwendet. Alle Ressourcen, einschließlich des Speichers, die diesen nicht verwendeten Daten zugewiesen sind, werden verschwendet. Die Aufgabe des Garbage Collector (GC) besteht darin, diesen verschwendeten Speicher zu beseitigen. Es wäre katastrophal für den GC, etwas zu eliminieren, das benötigt wird, daher könnte der verwendete Algorithmus konservativ sein und mehr als das strenge Minimum beibehalten. Möglicherweise werden heuristische Optimierungen verwendet, um die Geschwindigkeit zu verbessern, und zwar auf Kosten der Beibehaltung einiger Elemente, die nicht tatsächlich benötigt werden. Es gibt viele mögliche Algorithmen, die der GC verwenden könnte. Daher ist es möglich, dass Sie Änderungen an Ihrem Programm vornehmen, und die die Richtigkeit Ihres Programms nicht beeinträchtigen, können sich dennoch auf den Betrieb des GC auswirken, indem er entweder schneller ausgeführt wird, um denselben Job auszuführen, oder nicht verwendete Elemente früher identifiziert. Also diese Art von Änderung, auf die ein ungewöhnlicher Objektverweis gesetzt wird
null
, In der Theorie ist nicht immer Voodoo.Ist es Voodoo? Es gibt angeblich Teile des Java-Bibliothekscodes, die dies tun. Die Verfasser dieses Codes sind viel besser als durchschnittliche Programmierer und kennen Programmierer, die Details der Garbage Collector-Implementierungen kennen, oder arbeiten mit ihnen zusammen. Das deutet darauf hin, dass es manchmal einen Vorteil gibt.
quelle
Wie Sie sagten, gibt es Optimierungen, dh JVM kennt den Ort, an dem die Variable zuletzt verwendet wurde, und das Objekt, auf das sie verweist, kann direkt nach diesem letzten Punkt überprüft werden (wird immer noch im aktuellen Bereich ausgeführt). Das Aufheben von Referenzen in den meisten Fällen hilft GC also nicht.
Es kann jedoch nützlich sein, das Problem "Vetternwirtschaft" (oder "schwimmender Müll") zu vermeiden ( lesen Sie hier mehr oder sehen Sie sich ein Video an ). Das Problem besteht darin, dass der Heap in alte und junge Generationen aufgeteilt ist und verschiedene GC-Mechanismen angewendet werden: Minor GC (was schnell ist und häufig junge Gen reinigt) und Major Gc (was zu einer längeren Pause führt, um Old Gen zu reinigen). "Nepotismus" erlaubt nicht, dass Müll in der jungen Generation gesammelt wird, wenn er durch Müll referenziert wird, der bereits zu einer alten Generation gehört.
Um Vetternwirtschaft zu vermeiden, ist es eine gute Idee, Referenzen von einem Objekt, das entfernt werden soll, auf Null zu setzen. Sie können diese Technik in JDK-Klassen anwenden : LinkedList und LinkedHashMap
quelle