Heim  >  Artikel  >  Java  >  Einführung in Methoden zum Verbot der Verwendung von finalize in Java

Einführung in Methoden zum Verbot der Verwendung von finalize in Java

黄舟
黄舟Original
2017-10-14 09:37:551203Durchsuche

In diesem Artikel wird hauptsächlich das Verbot der Verwendung der Finalize-Methode in Java vorgestellt. Freunde, die sie benötigen, können darauf verweisen.

Was ist die Finalize-Methode?

finalize Die ()-Methode ist in der Klasse Java.lang.Object definiert, was bedeutet, dass alle Klassen diese Methode überschreiben können. Der Java-Garbage Collector kann nur über new zugewiesenen Speicher freigeben. Wenn Ihr Objekt also kein über new erhaltener Speicher ist, weiß der Garbage Collector nicht, wie er den Speicher des Objekts freigeben soll.

Um mit dieser Situation umzugehen, erlaubt Java, dass die Methode finalize() in der Klasse java.lang.Object in der Klasse überladen wird.

So funktioniert es: Sobald der Garbage Collector bereit ist, den vom Objekt belegten Speicherplatz freizugeben, wird zuerst seine finalize()-Methode aufgerufen und der vom Objekt belegte Speicher wird erst tatsächlich zurückgefordert Die nächste Garbage-Collection-Aktion findet statt.

Aufrufmechanismus der Finalisierungsfunktion

Die Java Virtual Machine-Spezifikation legt nicht streng fest, ob und wie die Garbage Collection durchgeführt werden soll . Daher kann nicht garantiert werden, dass der hier erwähnte Aufrufmechanismus für alle JVMs geeignet ist.

Wann heißt es?

Wann wird finalize aufgerufen? Im Allgemeinen wird es möglicherweise erst aufgerufen, wenn die JVM mit der Speicherbereinigung beginnt. Der Zeitpunkt, zu dem die JVM die Speicherbereinigung durchführt, ist sehr ungewiss und hängt von verschiedenen Faktoren der Laufzeitumgebung ab. Gerade aufgrund der Ungewissheit der Aufrufzeit der Finalisierungsfunktion kommt es zu einigen der später erwähnten Mängel.

Wer ruft an?

Common JVM ruft die Finalize-Funktion über den GC-Garbage-Collection-Thread auf. Da der Garbage-Collection-Thread sehr wichtig ist (schließlich ist er auch ein integraler Bestandteil der JVM), führt der Garbage-Collection-Thread Folgendes aus, um zu verhindern, dass die von der Finalize-Funktion ausgelöste Ausnahme den Betrieb des Garbage Collection-Threads beeinträchtigt Versuchen Sie es beim Aufrufen jeder Finalisierungsfunktion mit Catch. Wenn eine Ausnahme abgefangen wird, wird sie direkt verworfen und dann wird die Finalisierungsfunktion des nächsten ungültigen Objekts verarbeitet.

Warum ist die Verwendung von finalize() verboten?

1. Die Aufrufzeit ist ungewiss – es besteht ein Risiko der Verschwendung von Ressourcen

Der Aufrufmechanismus wurde bereits eingeführt. Die Studierenden sollten sich der Tatsache bewusst sein, dass „der Zeitpunkt des Aufrufs von finalize sehr ungewiss ist“. Wenn Sie daher in finalize() einige knappe Ressourcen freigeben, kann dies dazu führen, dass die knappen Ressourcen sehr, sehr lange warten müssen, bevor sie freigegeben werden. Das ist eine Verschwendung von Ressourcen! Darüber hinaus verbrauchen die von bestimmten Klassenobjekten (z. B. einigen JDBC-Klassen) bereitgestellten Ressourcen möglicherweise selbst viel Speicher, und die verzögerte Freigabe dieser Ressourcen führt zu großen Leistungsproblemen.

2. Darf nicht aufgerufen werden - es besteht die Gefahr eines Ressourcenverlusts

Viele Studenten denken, dass finalize() immer aufgerufen wird, aber das ist nicht der Fall . In einigen Fällen wird finalize() überhaupt nicht aufgerufen. Wenn beispielsweise die JVM beendet wird, werden die Finalisierungsfunktionen dieser Objekte im Speicher möglicherweise nicht aufgerufen.

Vielleicht denken einige Studenten über „runFinalizersOnExit“ nach, um sicherzustellen, dass alle Finalisierungen aufgerufen werden, bevor die JVM beendet wird. Es ist schade und bedauerlich, dass diese Methode seit JDK 1.2 aufgegeben wurde. Auch wenn diese Methode nicht aufgegeben wird, birgt sie immer noch ein großes Risiko für die Thread-Sicherheit! ​

Wie oben zu sehen ist, ist es sehr schlecht, wenn Sie sich erst einmal auf finalize() verlassen, um Ressourcen freizugeben (es besteht die Gefahr eines Ressourcenverlusts)! Oftmals sind durch Ressourcenlecks verursachte Leistungsprobleme schwerwiegender und sollten nicht unterschätzt werden.

3. Das Objekt kann wiederbelebt werden, wenn die Finalisierungsfunktion aufgerufen wird.

Ursprünglich ruft der Garbage Collector nur auf, wenn ein Objekt abgelaufen ist (keine Referenzen). Objekt-Finalisierungsfunktion. Wenn Sie jedoch auf einen perversen Programmierer stoßen und die eigene Referenz des Objekts (d. h. diese) irgendwo in der finalize()-Funktion erneut speichern, ist dies gleichbedeutend damit, sich selbst wiederzubeleben (da das Objekt eine neue Referenz hat und sich nicht mehr in einem ungültigen Zustand befindet). Zustand). Um zu verhindern, dass diese seltsame Sache passiert, kann der Garbage Collector nur nach jedem Aufruf von finalize() prüfen, ob sich das Objekt noch in einem ungültigen Zustand befindet. Dadurch erhöht sich der Overhead der JVM praktisch. Erwähnen Sie es einfach beiläufig. Wie in der JDK-Dokumentation festgelegt, ruft die JVM finalize() höchstens einmal für jede Klassenobjektinstanz auf. Daher wird finalize() bei gefälschten Leichen nicht aufgerufen, wenn diese tatsächlich sterben. Kommt Ihnen das nicht seltsam vor?

4. Denken Sie daran, Ausnahmen selbst abzufangen

Ich habe gerade bei der Einführung des finalize()-Aufrufmechanismus erwähnt, dass dies der Fall sein wird, sobald eine Ausnahme außerhalb der Finalize-Funktion ausgelöst wird Vom Garbage-Collection-Thread abgefangen und verworfen. Mit anderen Worten, die Ausnahme wird ignoriert (die Gefahren ignorierter Ausnahmen werden „hier“ erwähnt). Um so etwas zu verhindern, müssen Sie eine Try-Catch-Anweisung für jeden Code schreiben, der in finalize() eine Ausnahme auslösen könnte, und diese selbst abfangen.

5. Achten Sie auf die Thread-Sicherheit

Da finalize() von einem Garbage-Collection-Thread aufgerufen wird, handelt es sich nicht um denselben Thread wie Ihr eigener Code. Selbst finalize() verschiedener Objekte kann von verschiedenen Garbage-Collection-Threads aufgerufen werden (z. B. bei Verwendung eines „Parallelsammlers“); Wann). Wenn Sie in finalize() auf bestimmte Daten zugreifen, müssen Sie daher immer auf Thread-Sicherheitsprobleme achten.

Zusammenfassung

Das obige ist der detaillierte Inhalt vonEinführung in Methoden zum Verbot der Verwendung von finalize 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