Heim  >  Artikel  >  Java  >  Verwendung von Java-Objektzerstörungs- und Finalisierungsmethoden

Verwendung von Java-Objektzerstörungs- und Finalisierungsmethoden

王林
王林nach vorne
2023-04-15 09:58:05738Durchsuche

Zerstörung von Objekten

In C++ wird die Destruktormethode verwendet, um Ressourcen freizugeben und das Objekt selbst zu zerstören.

In Java müssen wir aufgrund der Existenz von GC den Speicher nicht manuell zurückfordern, was die Arbeitsbelastung erheblich reduziert und die Sicherheit des Programms verbessert. Aber Java hat eine ähnliche Funktion wie der Destruktor in C++.

finalize-Methode

Überladen Sie diese Methode, um einige Vorgänge auszuführen, wenn die Klasse von GC recycelt wird.

Das Folgende ist ein Beispiel für eine Klasse, die finalize implementiert.

Die Aoo-Klasse verfügt über ein int- und ein String-Attribut. Sie überlädt toString und gibt das Objekt und seine Erstellungszeit in der Konstruktion sowie das Objekt und die Aufrufzeit in finalize aus. „Aoo-Klasse“ 49754 7724059

GC-Recycling von Objekten

Hier wird der GC manuell aufgerufen, um den Speicher zu bereinigen, und wenn Sie System.gc(); auskommentieren, sieht das gedruckte Ergebnis wie folgt aus:

id:1 name:a now erstellen: 1497547846923

Das heißt, ohne ausdrücklichen Aufruf von GC wird die Finalize-Methode überhaupt nicht aufgerufen, was bedeutet, dass dieses Objekt überhaupt nicht aktiv recycelt wird.

Entgegen der Vorstellung ist der Betriebsmodus von GC faul, das heißt, wenn im Speicher kein Platz vorhanden ist, recycelt GC Objekte nicht aktiv. Um diese Idee zu überprüfen, habe ich einen Thread für den kontinuierlichen Speicherverbrauch erstellt und ruft GC nicht aktiv auf.


ThreadA-Klasse

public class Aoo {
       private int id;
       private String name;

       public Aoo(){
              this(0, null);
       }

       public Aoo(int id, String name){
              this.id = id;
              this.name = name;
              System.out.println(this.toString() + " now create:" + System.currentTimeMillis());
       }
        /*
        * 省略get/set/toString
        */
       protected void finalize() throws Throwable{
              super.finalize();
              System.out.println(this.toString() + "now finalize:" + System.currentTimeMillis());
       }
}

Hauptmethode

public class FinalizeTest {
       public static void main(String[] args) throws Exception {
              Aoo a = new Aoo(1, "a");
              a = null;
              System.gc()
              Thread.sleep(2000);
              System.exit(0);
       }
}
Druckergebnis:

id:1 Name:a jetzt erstellen:1497548135268

id:1 Name:anow. finalisieren:1497548135386

Obwohl es kein Handbuch gibt Diesmal wird der GC aufgerufen, aber die Finalisierungsmethode wird noch ausgeführt. Mit anderen Worten, der GC wird nur ausgeführt, wenn der Speicher verbraucht ist und der GC den Speicher bereinigen muss.

Eine solche Finalisierungsmethode ist wirklich unzuverlässig. Es ist nicht einmal sicher, ob sie aufgerufen werden kann, geschweige denn, dass sie einen bestimmten Vorgang abschließen muss. Wenn Sie den Stream schließen und Ressourcen wiederherstellen müssen, ist es besser, eine Methode manuell aufzurufen oder zu vereinheitlichen im letzten Block Ressourcen freigeben.

Müssen Sie bei der Finalisierungsmethode eine Referenz auf sich selbst neu zuweisen, um zu vermeiden, dass sie von GC recycelt wird?

Versuchen Sie, in der Finalize-Methode erneut zu referenzieren, um zu verhindern, dass GC recycelt wird.

Das geänderte Aoo lautet wie folgt: 1497551409195 es wird das Objekt nicht wieder „auferstehen“.

Hauptmethode zu
public class ThreadA implements Runnable{
       public void run() {
              List<Integer> list = new ArrayList<Integer>();
              int i = 0;
              while(true){
                     list.add(i);
                     i++;
              }
       }
}
E


Druckergebnisse:

ID: 1 Name: a, jetzt erstellen: 1497551587715

ID: 1 Name: beliebig Die beiden Vorgänge sind gleich und die Finalisierungsmethode wird von der nur einmal aufgerufen System.

Was passiert, wenn in der Finalze-Methode eine Endlosschleife auftritt?

Aoo-Klasse

public class FinalizeTest {
       public static void main(String[] args) throws Exception {
              Aoo a = new Aoo(1, "a");
              a = null;
              ThreadA ta = new ThreadA();
              Thread t = new Thread(ta);
              t.start();
              Thread.sleep(2000);
              System.exit(0);
       }
}

Hauptmethode

public class Aoo {
       public static Aoo SAVE = null;
       private int id;
       private String name;

       public Aoo(){
              this(0, null);
       }

       public Aoo(int id, String name){
              this.id = id;
              this.name = name;
              System.out.println(this.toString() + " now create:" + System.currentTimeMillis());
       }  
       /*
        * 省略get/set/toString
        */
       protected void finalize() throws Throwable{
              super.finalize();
              System.out.println(this.toString() + "now finalize:" + System.currentTimeMillis());
              SAVE = this;
       }
}
Druckergebnis:

id:1 Name:a1 jetzt erstellen:1497552024252
id:2 Name:a2 jetzt

id: 1 Name:a1now finalize:1497552024373
id:1 Name:a1now finalize:1497552024503
id:1 Name:a1now finalize:1497552026848

id:1 Name:a1now finalize:1497552028960
id:1 Name:a1now.finalize:1497552 0 32363

Das Ergebnis ist random wird manchmal das Finalisieren von a1 und manchmal das Finalisieren von a2 ausgeführt.

Dieses Ergebnis verdeutlicht zwei Punkte:

1 Die Thread-Priorität der Finalze-Methode ist sehr niedrig und das Zeitintervall ist ziemlich unsicher und offensichtlich größer als 100 Millisekunden.


2. Diese Endlosschleife führt dazu, dass die Finalize-Methode anderer Objekte nicht ausgeführt werden kann.

Wenn es bei der Objekterstellung eine solche Endlosschleife gibt, führt dies dazu, dass das Objekt nicht zerstört werden kann und ein Speicherüberlauf auftritt?

Wir erstellen eine große Anzahl von Aoo-Objekten und warten darauf, dass der GC den Speicher selbst zurückgewinnt.

Um den Aufruf der Finalize-Methode visuell zu beobachten, wurde der Druckcode bei der Initialisierung des Aoo-Objekts gelöscht.

Hauptmethode

public class FinalizeTest {
       public static void main(String[] args) throws Exception {
              Aoo.SAVE = new Aoo(1, "a");
              Aoo.SAVE = null;
              System.gc();
              Thread.sleep(500);
              System.out.println(Aoo.SAVE == null? "a is dead" : "a is alive" );              
              System.exit(0);             
       }
}

Lassen Sie das Programm etwa zwei Minuten lang ausführen, beenden Sie es dann manuell und überprüfen Sie die Ausgabe

1497554225913 :1497554227735

id:269614 Name:a269614jetzt finalisieren:1497554227836
id:269614 Name:a269614jetzt finalisieren:1497554229586
id:269614 Name:a269614jetzt finalisieren:1497554229686
id:269614 Name:a269614jetzt finalisieren:1497554229951
id:269614 Name:a269614jetzt finalisieren:14975 54230051
id:269614 Name:a269614now finalisieren:1497554230152
id:269614 Name:a269614now finalisieren:1497554233699
id:269614 Name:a269614jetzt finalisieren:1497554233800
id:269614 Name:a269614jetzt finalisieren:1497554233900
id:269614 Name:a269614jetzt finalisieren:14975 54234308
id:269614 Name:a269614jetzt finalisieren:1497554234408
id:269614 Name:a269614jetzt finalisieren:1497554234508
id:269614 Name:a269614jetzt finalisieren:1497554235053
id:269614 Name:a269614jetzt finalisieren:1497554235153
id:269614 Name:a269614jetzt finalisieren:14975 54235253
id:269614 Name:a269614jetzt finalisieren:1497554235823
id:269614 Name:a269614jetzt finalisieren:1497554235923
id:269614 Name:a269614jetzt finalisieren:1497554236023
id:269614 Name:a269614jetzt finalisieren:1497554240324
id:269614 Name:a269614jetzt finalisieren:14975 54240424
id:269614 Name:a269614now finalisieren:1497554240525
id:269614 Name:a269614now finalisieren:1497554241146
id:269614 Name:a269614jetzt finalisieren:1497554241247
id:269614 Name:a269614jetzt finalisieren:1497554241347
id:269614 Name:a269614jetzt finalisieren:14975 54241448
id:269614 Name:a269614jetzt finalisieren:1497554242020
id:269614 Name:a269614jetzt finalisieren:1497554242120
id:269614 Name:a269614jetzt finalisieren:1497554242220
id:269614 Name:a269614jetzt finalisieren:1497554242321
id:269614 Name:a269614jetzt finalisieren:14975 54242421
id:269614 Name:a269614jetzt finalisieren:1497554242521
id:269614 Name:a269614jetzt finalisieren:1497554248367
id:269614 Name:a269614jetzt finalisieren:1497554248467
id:269614 Name:a269614jetzt finalisieren:1497554248567
id:269614 Name:a269614jetzt finalisieren:14975 54248667
id:269614 Name:a269614jetzt finalisieren:1497554249534
id:269614 Name:a269614jetzt finalisieren:1497554249634
id:269614 Name:a269614jetzt finalisieren:1497554249734
id:269614 Name:a269614jetzt finalisieren:1497554249835
id:269614 Name:a269614jetzt finalisieren:14975 54255954
id:269614 Name:a269614now finalisieren:1497554256055
id:269614 Name:a269614now finalisieren:1497554256155
id:269614 Name:a269614jetzt finalisieren:1497554256255
id:269614 Name:a269614jetzt finalisieren:1497554256356
id:269614 Name:a269614jetzt finalisieren:14975 54257285
id:269614 Name:a269614now finalisieren:1497554257386
id:269614 Name:a269614now finalisieren:1497554257486
id:269614 Name:a269614jetzt finalisieren:1497554257586
id:269614 Name:a269614jetzt finalisieren:1497554257686
id:269614 Name:a269614jetzt finalisieren:14975 54268652
id:269614 Name:a269614now finalisieren:1497554268753
id:269614 Name:a269614now finalisieren:1497554268853
id:269614 Name:a269614jetzt finalisieren:1497554268953
id:269614 Name:a269614jetzt finalisieren:1497554269054
id:269614 Name:a269614jetzt finalisieren:14975 54269154
id:269614 Name:a269614now finalisieren:1497554277474
id:269614 Name:a269614now finalisieren:1497554292852
id:269614 Name:a269614jetzt finalisieren:1497554301062



可以发现两个情况:

1.只有一个对象的finalize方法被执行了, 也就是说这个死循环的finalize方法阻止了其他对象执行finalize方法2不断增加,finalize方法被执行的次数也就越来越少.

Das obige ist der detaillierte Inhalt vonVerwendung von Java-Objektzerstörungs- und Finalisierungsmethoden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen