Heim  >  Artikel  >  Java  >  Detaillierte Erläuterung von Beispielen für die Garbage Collection im Singleton-Modus in Java

Detaillierte Erläuterung von Beispielen für die Garbage Collection im Singleton-Modus in Java

黄舟
黄舟Original
2017-08-08 10:25:341595Durchsuche

In diesem Artikel werden hauptsächlich die relevanten Informationen zur Garbage Collection im Singleton-Modus ausführlich vorgestellt, die einen gewissen Referenzwert haben.

Diskussionsvorschlag: Wenn ein Singleton-Objekt nicht vorhanden ist Wird es über einen längeren Zeitraum hinweg vom Garbage-Collection-Mechanismus der JVM recycelt?

Lassen Sie mich zunächst darüber sprechen, warum diese Frage aufkommt. Der Autor hat noch nie zuvor über die Auswirkungen der Garbage Collection auf das Singleton-Muster nachgedacht, bis ich letztes Jahr ein Buch mit dem Titel „Zen of Design“ gelesen habe Muster“ 》 von Qin Xiaobo. Es wird im Buch erwähnt. In J2EE-Anwendungen behandelt der JVM-Garbage-Collection-Mechanismus Singleton-Objekte, die längere Zeit nicht verwendet wurden, als Müll und recycelt sie, wenn die CPU im Leerlauf ist. In den verschiedenen Designmusterbüchern, die ich zuvor gelesen habe, einschließlich „Java und Muster“, wurde der Einfluss des JVM-Garbage-Collection-Mechanismus auf Singletons nicht erwähnt. Und während des Arbeitsprozesses habe ich noch nie die Erfahrung gemacht, dass Singleton-Objekte recycelt werden. Außerdem haben mich viele Senioren bei der Arbeit gewarnt: Versuchen Sie, nicht zu viele statische Eigenschaften zu deklarieren, da diese statischen Eigenschaften nach dem Laden nicht freigegeben werden. Daher bin ich skeptisch gegenüber der Aussage, dass die JVM-Garbage Collection Singleton-Objekte recyceln wird. Nach und nach stellte ich fest, dass es unter meinen Kollegen und technischen Mitarbeitern im Internet im Grunde zwei gegnerische Fraktionen zu diesem Thema gab. Wird JVM also Singleton-Objekte recyceln, die längere Zeit nicht verwendet wurden?

Zu diesem Thema ist die persönliche Meinung des Autors: wird nicht recycelt .

Das Folgende ist mein Testcode


class Singleton {
 private byte[] a = new byte[6*1024*1024];
 private static Singleton singleton = new Singleton();
 private Singleton(){}
 
 public static Singleton getInstance(){
 return singleton;
 }
}

class Obj {
 private byte[] a = new byte[3*1024*1024];
}

public class Client{
 public static void main(String[] args) throws Exception{
 Singleton.getInstance();
 while(true){
  new Obj();
 }
 }
}

Der Zweck dieses Programms besteht darin, den j2ee-Container zu simulieren und zunächst zu instanziieren In der Singleton-Klasse belegt diese Singleton-Klasse 6 MB Speicher. Anschließend tritt das Programm in eine Endlosschleife ein, in der ständig Objekte erstellt werden, wodurch die JVM gezwungen wird, eine Garbage Collection durchzuführen und dann die Garbage Collection-Informationen zu beobachten, wenn der Speicher danach immer noch größer als 6 MB ist Garbage Collection bedeutet, dass Singleton-Objekte nicht recycelt werden.

Die zum Ausführen dieses Programms verwendete virtuelle Maschine ist die virtuelle Hotspot-Maschine, die offiziell von Java bereitgestellte virtuelle Maschine, die wir am häufigsten verwenden. Sie wird allgemein als jdk bezeichnet und hat die Version jdk1.6.0_12

Die Laufzeit-VM-Argumentparameter sind: -verbose:gc -Xms20M -Xmx20M, was bedeutet, dass die Speicherinformationen jedes Mal angezeigt werden, wenn der JVM eine Speicherbereinigung durchführt und der Speicher des JVM auf einen festen Wert eingestellt ist 20M.

Laufergebnis:

……
[Full GC 18566K->6278K(20352K), 0.0101066 secs]
[GC 18567K->18566K(20352K), 0.0001978 secs]
[Full GC 18566K->6278K(20352K), 0.0088229 secs]
……


Anhand des Laufergebnisses können Sie erkennen, dass es welche gibt insgesamt 6 Mio. Speicherplatz. Nicht gesammelt. Daher ist der Autor der Ansicht, dass die Speicherbereinigung zumindest in der virtuellen Hotspot-Maschine keine Singleton-Objekte recycelt.

Später habe ich einige relevante Informationen überprüft. Der Garbage Collection-Algorithmus der virtuellen Hotspot-Maschine verwendet den Root-Suchalgorithmus. Die Grundidee dieses Algorithmus ist: Für jedes „lebende“ Objekt muss es letztendlich auf seine Referenz zurückgeführt werden, die im Stapel oder im statischen Speicherbereich verbleibt. Unter Verwendung einer Reihe von Referenzen namens Roots (GC Roots) als Ausgangspunkt, ausgehend von diesen Roots und der Suche über eine Reihe von Pfaden: Wenn das Objekt im Java-Heap erreicht werden kann, ist das Objekt „live“ und kann nicht recycelt werden . Objekte, die als Roots verwendet werden können, sind:

  •  Objekte, auf die im Stapel der virtuellen Maschine verwiesen wird (lokale Variablentabelle im Stapelrahmen).

  •  Das Objekt, auf das von der statischen Eigenschaft der Klasse im Methodenbereich verwiesen wird.

  •  Das Objekt, auf das die Konstante im Methodenbereich verweist.

  •  Das von JNI referenzierte Objekt im lokalen Methodenstapel.

Der Methodenbereich ist ein Speicherbereich der JVM, in dem klassenbezogene Informationen gespeichert werden. Offensichtlich wird das durch den Singleton-Modus in Java erstellte Objekt durch die statischen Eigenschaften in seiner eigenen Klasse referenziert, was dem zweiten Artikel entspricht. Daher wird das Singleton-Objekt nicht von der JVM gesammelt.

Obwohl das Singleton-Objekt im JVM-Heap nicht durch Müll gesammelt wird, wird die Singleton-Klasse selbst gesammelt, wenn sie längere Zeit nicht verwendet wird? Denn JVM verfügt auch über einen Garbage-Collection-Mechanismus für den Methodenbereich. Wenn die Singleton-Klasse gesammelt wird, verlieren die Objekte im Heap ihren Pfad zum Stamm und werden unweigerlich durch Müll gesammelt. In diesem Zusammenhang hat der Autor die Garbage Collection-Methode der virtuellen Hotspot-Maschine für den Methodenbereich herangezogen. Die Beurteilungsbedingungen für JVM-Entladeklassen lauten wie folgt:

  • Alle Instanzen dieser Klasse wurden recycelt. Das heißt, es gibt keine Instanz dieser Klasse im Java-Heap.

  • Der ClassLoader, der diese Klasse geladen hat, wurde recycelt.

  • Auf das dieser Klasse entsprechende java.lang.Class-Objekt wird nirgendwo verwiesen, und auf die Methoden dieser Klasse kann nirgendwo durch Reflektion zugegriffen werden.

Nur wenn drei Bedingungen erfüllt sind, entlädt der JVM die Klasse während der Speicherbereinigung. Offensichtlich erfüllt die Singleton-Klasse Bedingung 1 nicht, sodass die Singleton-Klasse nicht entladen wird. Mit anderen Worten, solange die statische Referenz in der Singleton-Klasse auf das Singleton-Objekt im JVM-Heap verweist, werden die Singleton-Klasse und das Singleton-Objekt gemäß dem Root-Suchalgorithmus nicht durch Müll gesammelt gesammelt oder nicht. Die Nutzungsdauer spielt keine Rolle, es kommt lediglich darauf an, ob das Objekt „lebendig“ ist. Wenn ein Objekt längere Zeit nicht verwendet wurde und recycelt wird, sollte der Sammelalgorithmus der am längsten nicht verwendete Algorithmus sein, der im Allgemeinen beim internen und externen Speicheraustausch des Betriebssystems verwendet wird Wäre es nicht zu unsicher, wenn es in der Garbage Collection für virtuelle Maschinen verwendet wird? Das Obige ist die Meinung des Autors.

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung von Beispielen für die Garbage Collection im Singleton-Modus in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn