Ich habe einige alte Bücher durchgesehen und eine Kopie von "Practical Java" von Peter Hagger gefunden. Im Leistungsabschnitt gibt es eine Empfehlung, Objektreferenzen festzulegen, auf die null
nicht mehr benötigt wird.
Werden in Java Objektreferenzen festgelegt, null
um die Leistung oder die Effizienz der Speicherbereinigung zu verbessern? Wenn ja, in welchen Fällen ist dies ein Problem? Containerklassen? Objektzusammensetzung? Anonyme innere Klassen?
Ich sehe das ziemlich oft im Code. Ist dies jetzt veraltete Programmierempfehlung oder ist es immer noch nützlich?
Antworten:
Es hängt ein wenig davon ab, wann Sie daran gedacht haben, die Referenz auf Null zu setzen.
Wenn Sie eine Objektkette A-> B-> C haben, können A, B und C, sobald A nicht erreichbar ist, alle zur Speicherbereinigung berechtigt sein (vorausgesetzt, nichts anderes bezieht sich auf B oder C). Es besteht keine Notwendigkeit und war auch nie eine Notwendigkeit, die Referenzen A-> B oder B-> C beispielsweise explizit auf Null zu setzen.
Abgesehen davon tritt das Problem meistens nicht wirklich auf, da es sich in Wirklichkeit um Objekte in Sammlungen handelt. Sie sollten im Allgemeinen immer daran denken, Objekte aus Listen, Karten usw. zu entfernen, indem Sie die entsprechende remove () -Methode aufrufen.
Der Fall, in dem es früher einige Ratschläge gab, Verweise auf Null zu setzen, war speziell in einem langen Bereich, in dem ein speicherintensives Objekt während des gesamten Bereichs nicht mehr verwendet wurde . Beispielsweise:
Der Grund hierfür war, dass obj , da es sich noch im Gültigkeitsbereich befindet, ohne die explizite Nullung der Referenz erst nach Abschluss der Methode doSomethingElse () zur Speicherbereinigung wird . Und dies ist der Rat, den moderne JVMs wahrscheinlich nicht mehr haben : Es stellt sich heraus, dass der JIT-Compiler herausfinden kann, an welchem Punkt eine bestimmte lokale Objektreferenz nicht mehr verwendet wird.
quelle
Nein, es ist kein veralteter Rat. Baumelnde Referenzen sind immer noch ein Problem, insbesondere wenn Sie beispielsweise einen erweiterbaren Array-Container (
ArrayList
oder dergleichen) mithilfe eines vorab zugewiesenen Arrays implementieren . Elemente, die über die "logische" Größe der Liste hinausgehen, sollten auf Null gesetzt werden, da sie sonst nicht freigegeben werden.Siehe Effective Java 2nd ed, Punkt 6: Veraltete Objektreferenzen beseitigen.
quelle
Instanzfelder, Array-Elemente
Wenn auf ein Objekt verwiesen wird, kann kein Müll gesammelt werden. Insbesondere wenn dieses Objekt (und das gesamte Diagramm dahinter) groß ist, gibt es nur eine Referenz, die die Speicherbereinigung stoppt, und diese Referenz wird nicht mehr wirklich benötigt. Dies ist eine unglückliche Situation.
Pathologische Fälle sind das Objekt, das eine unnötige Instanz für den gesamten XML-DOM-Baum beibehält, der zum Konfigurieren verwendet wurde, die MBean, die nicht abgemeldet wurde, oder der einzelne Verweis auf ein Objekt aus einer nicht bereitgestellten Webanwendung, der verhindert, dass ein ganzer Klassenladeprogramm entladen wird .
Wenn Sie also nicht sicher sind, dass das Objekt, das die Referenz selbst enthält, ohnehin (oder sogar dann) Müll gesammelt wird, sollten Sie alles auf Null setzen, was Sie nicht mehr benötigen.
Gültigkeitsbereichsvariablen:
Wenn Sie erwägen, eine lokale Variable vor dem Ende ihres Gültigkeitsbereichs auf null zu setzen, damit sie vom Garbage Collector zurückgefordert und als "von nun an unbrauchbar" markiert werden kann, sollten Sie sie stattdessen in einen eingeschränkteren Gültigkeitsbereich verschieben .
wird
Lange, flache Bereiche sind im Allgemeinen auch für die Lesbarkeit des Codes schlecht. Die Einführung privater Methoden, um Dinge nur für diesen Zweck aufzubrechen, ist ebenfalls keine Seltenheit.
quelle
In speicherbeschränkenden Umgebungen (z. B. Mobiltelefonen) kann dies nützlich sein. Wenn Sie null setzen, muss der objetc nicht auf die Variable warten, um den Bereich zu verlassen, der gc'd werden soll.
Für die alltägliche Programmierung sollte dies jedoch nicht die Regel sein, außer in besonderen Fällen wie dem von Chris Jester-Young genannten.
quelle
Erstens bedeutet es nichts, auf das Sie ein Objekt setzen
null
. Ich erkläre es unten:Im obigen Codesegment erstellen wir den Namen
list1
derArrayList
Objektreferenzvariablen des Objekts, das im Speicher gespeichert ist. Verweistlist1
also auf dieses Objekt und es ist nichts weiter als eine Variable. Und in der zweiten Codezeile kopieren wir den Verweislist1
auflist2
. Kommen wir nun zu Ihrer Frage zurück, wenn ich das tue:Das bedeutet, dass
list1
kein Objekt mehrlist2
referenziert wird, das im Speicher gespeichert ist, und dass auch nichts mehr referenziert werden muss. Wenn Sie also die Größe von überprüfenlist2
:Hier kommt also das Konzept des Garbage Collector, das besagt: "Sie brauchen sich keine Sorgen um die Freigabe des vom Objekt gehaltenen Speichers zu machen. Ich werde dies tun, wenn ich feststelle, dass es nicht mehr im Programm verwendet wird und JVM mich verwaltet."
Ich hoffe es klärt das Konzept.
quelle
Einer der Gründe dafür ist die Beseitigung veralteter Objektreferenzen. Den Text können Sie hier lesen .
quelle