it-swarm.com.de

Hat das Setzen von Java-Objekten auf null irgendetwas?

Ich habe einige alte Bücher durchsucht und eine Kopie von "Practical Java" von Peter Hagger gefunden. Im Performance-Abschnitt wird empfohlen, Objektreferenzen auf null zu setzen, wenn sie nicht mehr benötigt werden. 

Verbessert das Setzen von Objektverweisen auf null in Java die Leistung oder die Garbage Collection-Effizienz? Wenn ja, in welchen Fällen ist dies ein Problem? Containerklassen Objektkomposition Anonyme innere Klassen?

Ich sehe das ziemlich oft im Code. Ist das jetzt veraltete Programmierungsempfehlung oder ist es noch nützlich? 

104
sal

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, sind A, B und C, sobald A nicht erreichbar ist, alle für die Garbage Collection berechtigt (vorausgesetzt, nichts anderes bezieht sich auf B oder C). Es ist nicht erforderlich und war auch noch nie erforderlich, die Referenzen A-> B oder B-> C 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, Maps usw. zu entfernen, indem Sie die entsprechende remove () -Methode aufrufen.

Der Fall, in dem früher einige Hinweise zum Festlegen von Verweisen auf null gegeben wurden, lag speziell in einem langen Bereich, in dem ein speicherintensives Objekt während des gesamten Gültigkeitsbereichs nicht mehr verwendet wurde. Zum Beispiel:

{
  BigObject obj = ...
  doSomethingWith(obj);
  obj = null;             <-- explicitly set to null
  doSomethingElse();
}

Der Grund hierfür war, dass obj noch im Gültigkeitsbereich ist und erst nach dem doSomethingElse gesammelt werden kann, wenn der Verweis explizit auf null gesetzt wird () Methode wird abgeschlossen. Und dies ist der Rat, den der bei modernen JVMs wahrscheinlich nicht mehr gilt: Es stellt sich heraus, dass der JIT-Compiler herausfinden kann, an welchem ​​Punkt eine bestimmte lokale Objektreferenz nicht mehr verwendet wird.

70
Neil Coffey

Nein, es ist kein veralteter Rat. Verhängnisvolle Referenzen sind immer noch ein Problem, insbesondere wenn Sie einen erweiterbaren Array-Container (ArrayList oder ähnliches) mit einem vorab zugewiesenen Array implementieren. Elemente, die über die "logische" Größe der Liste hinausgehen, sollten auf Null gesetzt werden, andernfalls werden sie nicht freigegeben.

Siehe Effektives Java 2nd Ed, Punkt 6: Beseitigen Sie obsolete Objektreferenzen.

25

Instanzfelder, Arrayelemente

Wenn es einen Verweis auf ein Objekt gibt, kann es nicht zur Abfallsammlung verwendet werden. Vor allem, wenn das Objekt (und das gesamte Diagramm dahinter) groß ist, gibt es nur eine Referenz, die die Garbage Collection stoppt, und diese Referenz ist nicht mehr wirklich erforderlich. Das ist eine unglückliche Situation.

Pathologische Fälle sind das Objekt, das eine nicht notwendige Instanz für die gesamte XML-DOM-Struktur enthält, die zum Konfigurieren verwendet wurde, die nicht registrierte MBean oder die einzelne Referenz auf ein Objekt aus einer nicht bereitgestellten Webanwendung, die das Entladen eines gesamten Klassenladeprogramms verhindert .

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.

Bereichsvariablen:

Wenn Sie in Erwägung ziehen, eine lokale Variable vor dem Ende ihres Gültigkeitsbereichs auf null zu setzen, damit sie vom Garbage Collector zurückgefordert werden kann und sie als "unbrauchbar von jetzt an" kennzeichnen kann, sollten Sie stattdessen einen begrenzten Geltungsbereich verwenden .

{
  BigObject obj = ...
  doSomethingWith(obj);
  obj = null;          //   <-- explicitly set to null
  doSomethingElse();
}

wird 

{
  {  
     BigObject obj = ...
     doSomethingWith(obj);
  }    //         <-- obj goes out of scope
  doSomethingElse();
}

Lange, flache Bereiche sind im Allgemeinen auch für die Lesbarkeit des Codes schlecht. Auch die Einführung privater Methoden, um die Dinge nur für diesen Zweck aufzuteilen, ist nicht ungewöhnlich.

10
Thilo

In speicherbegrenzenden Umgebungen (z. B. Mobiltelefonen) kann dies nützlich sein. Durch das Setzen von null muss das Objekt nicht auf die Variable warten, um aus dem Gültigkeitsbereich zu gelangen, um gc zu sein.

Für die tägliche Programmierung sollte dies jedoch nicht die Regel sein, außer in besonderen Fällen wie dem von Chris Jester-Young zitierten.

5
besen

Erstens bedeutet es nicht, dass Sie ein Objekt auf null setzen. Ich erkläre es unten:

List list1 = new ArrayList();
List list2 = list1;

Im obigen Codesegment erstellen wir den Objektreferenzvariablennamen list1 des ArrayList-Objekts, das im Speicher gespeichert ist. list1 verweist also auf dieses Objekt und es ist nichts weiter als eine Variable. Und in der zweiten Codezeile kopieren wir die Referenz von list1 nach list2. Nun zurück zu Ihrer Frage, wenn ich es tue:

list1 = null;

das heißt, list1 verweist nicht mehr auf Objekte, die im Speicher abgelegt sind, so dass list2 auch nichts zu referenzieren hat. Wenn Sie also die Größe von list2 überprüfen:

list2.size(); //it gives you 0

Hier kommt also das Konzept des Garbage Collectors, in dem «Sie brauchen sich keine Sorgen zu machen, dass der Speicher, den das Objekt enthält, freigegeben wird. Ich werde das tun, wenn ich feststelle, dass er nicht mehr im Programm verwendet wird und JVM mich verwaltet. »

Ich hoffe es klärt das Konzept.

1
Aman Goel

Ein Grund dafür ist, obsolete Objektreferenzen zu entfernen. Den Text können Sie hier lesen.

0
Sudip Bhandari