Ich muss wissen, wann die [finalize()
](https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#finalize()) Methode wird in der JVM
. Ich habe eine Testklasse erstellt, die in eine Datei schreibt, wenn die finalize()
Methode aufgerufen wird, indem sie überschrieben wird. Sie wird nicht ausgeführt. Kann mir jemand den Grund dafür nennen, warum sie nicht ausgeführt wird?
Antworten
Zu viele Anzeigen?Manchmal muss ein Objekt, wenn es zerstört wird, eine Aktion durchführen. Wenn ein Objekt beispielsweise eine Nicht-Java-Ressource wie ein Dateihandle oder eine Schriftart besitzt, können Sie vor der Zerstörung eines Objekts überprüfen, ob diese Ressourcen freigegeben sind. Um solche Situationen zu bewältigen, bietet Java einen Mechanismus namens "Finalisieren". Durch Finalisieren können Sie bestimmte Aktionen definieren, die ausgeführt werden, wenn ein Objekt vom Garbage Collector entfernt werden soll. Um einen Finalizer zu einer Klasse hinzuzufügen, definieren Sie einfach die finalisieren() Methode. Die Java-Ausführungszeit ruft diese Methode immer dann auf, wenn sie im Begriff ist, ein Objekt dieser Klasse zu löschen. Innerhalb der finalize Methode() geben Sie Aktionen an, die vor der Zerstörung eines Objekts ausgeführt werden sollen. Der Garbage Collector wird periodisch nach Objekten durchsucht, die sich nicht mehr auf einen laufenden Zustand oder indirekt auf ein anderes Objekt beziehen. Bevor ein Asset freigegeben wird, ruft die Java-Laufzeit die Funktion finalisieren() Methode auf das Objekt. Die finalisieren() Methode hat die folgende allgemeine Form:
protected void finalize(){
// This is where the finalization code is entered
}
Mit dem geschützt Schlüsselwort, Zugang zu finalisieren() durch klassenfremden Code wird verhindert. Es ist wichtig zu verstehen, dass finalisieren() wird kurz vor der Garbage Collection aufgerufen. Er wird nicht aufgerufen, wenn ein Objekt beispielsweise den Geltungsbereich verlässt. Das heißt, Sie können nicht wissen, wann oder ob, finalisieren() ausgeführt werden. Infolgedessen muss das Programm andere Mittel bereitstellen, um Systemressourcen oder andere vom Objekt verwendete Ressourcen freizugeben. Sie sollten sich nicht auf finalisieren() für die normale Ausführung des Programms.
Aktuelle Neuigkeiten von JDK 18
Nach Angaben von JEPS 421 auf openjdk 18 die Fertigstellung und damit die Funktionalität von finalize()
Methode wird markiert als deprecated(forRemoval=true)
Das bedeutet, dass die dauerhafte Entfernung in einer späteren Version nach jdk 18 erfolgen würde.
Ab jdk 18 gibt es eine neue Kommandozeilenoption --finalization=disabled
deaktiviert den Finalisierungsmechanismus überall, auch für Deklarationen innerhalb des JDK selbst.
Dies ist auch für die vorliegende Frage relevant, denn der Grund für die geplante Abschaffung sind einige schwerwiegende Mängel, die sie enthält. Einer dieser Fehler ist, dass zwischen dem Moment, in dem ein Objekt unerreichbar wird, und dem Moment, in dem sein Finalizer aufgerufen wird, eine sehr lange Zeit vergehen kann. Es ist auch wahr, dass die GC keine Garantie dafür bietet, dass ein Finalizer jemals aufgerufen wird.
Klasse, in der wir die finalize-Methode außer Kraft setzen
public class TestClass {
public TestClass() {
System.out.println("constructor");
}
public void display() {
System.out.println("display");
}
@Override
public void finalize() {
System.out.println("destructor");
}
}
Die Wahrscheinlichkeit, dass die finalize-Methode aufgerufen wird
public class TestGarbageCollection {
public static void main(String[] args) {
while (true) {
TestClass s = new TestClass();
s.display();
System.gc();
}
}
}
wenn der Speicher mit Dump-Objekten überlastet ist, ruft gc die finalize-Methode auf
ausführen und sehen Sie die Konsole, wo Sie nicht finden, die finalize-Methode häufig aufgerufen wird, wenn der Speicher immer überlastet ist dann die finalize-Methode aufgerufen werden.
finalize()
wird kurz vor der Garbage Collection aufgerufen. Er wird nicht aufgerufen, wenn ein Objekt den Gültigkeitsbereich verlässt. Das bedeutet, dass Sie nicht wissen können, wann oder ob überhaupt finalize()
ausgeführt werden.
Beispiel:
Wenn Ihr Programm vor dem Auftreten des Garbage Collectors endet, dann finalize()
wird nicht ausgeführt. Daher sollte es als Backup-Verfahren verwendet werden, um die ordnungsgemäße Handhabung anderer Ressourcen zu gewährleisten, oder für spezielle Anwendungen, nicht als das Mittel, das Ihr Programm in seinem normalen Betrieb verwendet.