it-swarm.com.de

Sind statische Felder für die Garbage Collection geöffnet?

Angenommen, eine hypothetische Dienstprogrammklasse, die nur in der Programmkonfiguration verwendet wird:

class MyUtils {
   private static MyObject myObject = new MyObject();
   /*package*/static boolean doStuff(Params... params) {
       // do stuff with myObject and params...
   }
}

wird myObject bei der Nichtbenutzung Müll gesammelt oder bleibt es für die gesamte Lebensdauer des Programms erhalten?

80

Statische Variablen können nicht für die Garbage Collection ausgewählt werden, während die Klasse geladen wird. Sie können abgeholt werden, wenn der jeweilige Klassenlader (der für das Laden dieser Klasse verantwortlich war) selbst für Müll gesammelt wird.

Schauen Sie sich die JLS-Sektion 12.7 an. Entladen von Klassen und Schnittstellen

Eine Klasse oder Schnittstelle kann entladen werden wenn und nur dann, wenn die definierende Klasse Der Lader kann vom Müll zurückgefordert werden Abnehmer [...] Klassen und Schnittstellen geladen vom Bootstrap-Loader darf nicht entladen werden.

101
bruno conde

Statische Variablen werden von Class-Objekten referenziert, auf die von ClassLoaders verwiesen wird. Dies gilt nicht, wenn der ClassLoader die Klasse auf irgendeine Weise (wenn überhaupt möglich) löscht oder der ClassLoader selbst die statischen Variablen (oder das Entladen von Webapps) sammeln kann Die Objekte, auf die sie verweisen, werden nicht gesammelt.

45
Jon Skeet

Wenn Sie möchten, dass ein temporäres Objekt zur statischen Initialisierung verwendet und anschließend entsorgt wird, können Sie einen statischen Initialisierungsblock verwenden, z.

class MyUtils {
   static
   {
      MyObject myObject = new MyObject();
      doStuff(myObject, params);
   }

   static boolean doStuff(MyObject myObject, Params... params) {
       // do stuff with myObject and params...
   }
}

da der statische Initialisierungsblock eine spezielle Art statischer Methode ist, ist myObject eine lokale Variable, die nach Abschluss der Blockbereinigung abgefangen werden kann.

13
finnw

myObject ist ein Verweis und kein Objekt ..__ Ein Objekt wird automatisch Müll gesammelt, wenn keine Referenz darauf verweist, weil es nicht erreichbar ist.

So kann auch das Objekt hinter einem statischen Verweis "myObject" aufgesammelt werden, wenn Sie es mit dereferenzieren

myObject = null;

es gibt keine weiteren Verweise auf dieses Objekt.

Statische Referenzen und Variablen bleiben jedoch für die gesamte Lebensdauer Ihres Programms erhalten.

9
Felix Keil

Ich denke, das beantwortet Ihre Frage - im Grunde nicht, es sei denn, die Klasse kommt aus einem speziellen Klassenlader und entlädt die Klasse.

6
Tom

Der Schlüssel hier ist die Garbage Collection von Klasseninstanzen, d. H. Objekten. Die ClassLoader-Instanz ist im Wesentlichen ein Objekt. Wenn also das Classloader-Objekt nicht mit Garbage Collected belegt ist, werden Referenzen von ihnen, die in Heap gespeichert sind (d. H. Statische Daten), so gut wie nie mit Garbage Collected belegt. Die Ausnahme ist String Pool.

Also, bevor Sie sich plötzlich dazu entschließen, private static MyGiantClass myGiantObject = new MyGiantClass() zu tun, überlegen Sie zweimal, wie ich es auf die harte Tour gelernt habe.

0
ha9u63ar