Wann ist die finalize () - Methode aufgerufen, die in Java?
Muss ich wissen, wenn die finalize()
Methode wird aufgerufen, in der JVM
. Ich erstellte eine test-Klasse, die schreibt in eine Datei, wenn die finalize()
Methode wird aufgerufen, durch überschreiben es. Es ist nicht ausgeführt. Kann mir jemand sagen, der Grund, warum es nicht ausgeführt wird?
Nur als Anmerkung: abschließen ist als veraltet markiert in Java 9
werfen Sie einen Blick: infoq.com/news/2017/03/Java-Finalize-Deprecated
wenn etwas hat eine Referenz auf Ihr Objekt oder auch die Klasse.
werfen Sie einen Blick: infoq.com/news/2017/03/Java-Finalize-Deprecated
wenn etwas hat eine Referenz auf Ihr Objekt oder auch die Klasse.
finalize()
- und garbage-collection hat keine Auswirkung.InformationsquelleAutor Rajesh Kumar J | 2010-03-24
Du musst angemeldet sein, um einen Kommentar abzugeben.
Im Allgemeinen ist es am besten nicht zu verlassen Sie sich auf
finalize()
zu tun Aufräumen etc.Entsprechend der Javadoc (was es Wert wäre zu Lesen), es ist:
Als Joachim wies darauf hin, dies vielleicht auch nie im Leben ein Programm, wenn das Objekt ist immer zugänglich.
Auch, dass der garbage collector nicht garantiert ist, laufen zu einem bestimmten Zeitpunkt. Im Allgemeinen, was ich versuche zu sagen ist
finalize()
ist wahrscheinlich nicht die beste Methode zu verwenden, im Allgemeinen, es sei denn, es ist etwas besonderes, Sie brauchen es für."nicht die beste Methode zu verwenden... es sei denn, es ist etwas besonderes, Sie brauchen es für" - äh, dieser Satz gilt für 100% der alles, so ist das nicht hilfreich. Joachim Sauer, die Antwort ist viel besser
dein Beispiel ist hilfreich für die Klärung, sondern nur zu pedantisch, vermutlich könnte es genannt werden, die auf die main Klasse, wenn die main-Klasse erzeugt ein nicht-daemon-thread und kehrt dann zurück?
Also, was sind die Situationen, in denen
finalize
nützlich wäre?Das ist eigentlich irrelevant. Die
finalize()
Methode der main-Klasse aufgerufen wird, wenn ein >>Beispiel<< die Klasse ist Müll gesammelt, auch nicht, wenn die main-Methode beendet wird. Und außerdem, die main-Klasse könnte garbage Collection ausgeführt werden, bevor die Anwendung beendet wird; z.B. in einer multi-threaded-app, wo die "Haupt" - thread erzeugt andere threads und kehrt dann zurück. (In der Praxis, eine nicht-standard-classloader, der erforderlich sein würde ....)InformationsquelleAutor
Den
finalize
Methode wird aufgerufen, wenn ein Objekt über Müll gesammelt. Das können Sie jederzeit, nachdem es geworden ist, für die garbage collection freigegeben.Beachten Sie, dass es durchaus möglich, dass ein Objekt nie Müll gesammelt (und damit
finalize
wird nie aufgerufen). Dies kann passieren, wenn das Objekt nie wird kommen für gc (weil es ist erreichbar über die gesamte Lebensdauer der JVM) oder, wenn keine garbage collection ausgeführt wird zwischen der Zeit, in das Objekt zu kommen und die Zeit, die die JVM beendet wird (dies geschieht Häufig mit einfachen test-Programmen).Gibt es Möglichkeiten, zu sagen, der JVM ausgeführt
finalize
auf Objekte, die es nicht als auf noch, aber mit Ihnen ist keine gute Idee, (die garantiert, dass die Methode nicht sehr stark).Wenn du dich auf
finalize
für den korrekten Betrieb der Anwendung, dann machen Sie etwas falsch.finalize
sollte nur verwendet werden, für die Beseitigung von (in der Regel nicht-Java -) Ressourcen. Und das ist genau, weil die JVM keine Garantie, dassfinalize
wird immer aufgerufen, für jedes Objekt.der perfekte Ersatz ist nichts: Sie sollten nicht erforderlich sein. Der einzige Fall, wo es Sinn machen würde, ist, wenn Sie Ihre Klasse verwaltet die externen Ressourcen (wie ein TCP/IP-Verbindung, Datei, ... alles, was der Java-GC nicht umgehen kann). In diesen Fällen wird die
Closable
interface (und die Idee dahinter) ist wahrscheinlich das, was Sie wollen: machen.close()
schließen/verwerfen Sie die Ressource und erfordern, dass der Benutzer Ihrer Klasse nennen Sie es an der richtigen Zeit. Sie könnte hinzufügen möchtenfinalize
Methode "nur speichern", aber das wäre eher ein debugging-tool als eine eigentliche Korrektur (weil es nicht zuverlässig genug).das ist eigentlich eine ganz andere Frage und sollte GESONDERT erfragt werden. Es gibt shutdown-hooks, aber Sie sind nicht garantiert, wenn die JVM unerwartet beendet wird (ein.k.ein. stürzt ab). Aber Ihre Garantien sind deutlich stärker als jene für Finalizer (und Sie sind sicherer als auch).
Ihrem letzten Absatz sagt, es zu benutzen nur für das bereinigen von Ressourcen, obwohl es keine Garantie es wird immer aufgerufen werden. Ist dieser Optimismus genommen??? Ich würde davon ausgehen, dass etwas unzuverlässig, da wäre das nicht geeignet für die Reinigung von Ressourcen.
Finalizer kann manchmal den Tag retten... ich hatte einen Fall, wo eine 3rd-party-Bibliothek wurde mit einem FileInputStream, nie schließen. Meiner war der code für den Aufruf des library-code, und dann versucht, um die Datei zu verschieben, zu scheitern, weil es noch offen war. Ich musste mich zwingen, rufen
System.gc()
aufrufen FileInputStream::finalize(), dann könnte ich die Datei verschieben.InformationsquelleAutor Joachim Sauer
zitiert aus: http://www.janeg.ca/scjp/gc/finalize.html
Könnte man auch diesen Artikel:
Da runFinalizerOnExit() ist NICHT thread-sicher, was man machen könnte, ist die Laufzeit.getRuntime().addShutdownHook(new Thread() { public void run() { destroyMyEnclosingClass(); } }); im Konstruktor der Klasse.
Sangat ist Das ein Weg, es zu tun, aber denken Sie daran, dies setzt eine Referenz auf die Instanz aus der shutdownHook, die so ziemlich garantiert, dass Ihre Klasse ist nie Müll gesammelt. In anderen Worten, es ist ein Speicher-Leck.
während ich Stimme allen anderen hier in Bezug auf nicht zu verwenden finalize() für etwas, das ich nicht sehen warum es hätte ein Verweis aus dem shutdown-hook. Man könnte eine weiche Referenz.
InformationsquelleAutor XpiritO
Java
finalize()
Methode ist kein Destruktor und sollte nicht verwendet werden, zu handhaben Logik, die von Ihrer Anwendung abhängt. Die Java-spec-Staaten gibt es keine Garantie, dass diefinalize
Methode wird aufgerufen, bei der livetime der Anwendung.Was Sie auf bestem Wege begraben wollen, ist eine Kombination von
finally
und eine cleanup-Methode, in:InformationsquelleAutor rsp
Check-out Effektiv Java, 2. Auflage, Seite 27.
Punkt 7: Vermeiden Sie Finalizer
Zu beenden, eine Ressource, verwenden Sie try-finally statt:
Dieser übernimmt die Lebensdauer eines Objekts in der scope einer Funktion. Was natürlich nicht der Fall ist, dass der OP sich bezieht, noch ist es der Fall im Grunde alle Bedürfnisse. Denke "cache engine Rückgabewert reference count". Sie wollen kostenlos den cache-Eintrag, wenn der Letzte ref freigegeben wird, aber Sie wissen nicht, Wann der Letzte ref freigegeben wird. finalize() kann Dekrementieren einen ref-Anzahl, zum Beispiel... aber wenn Sie benötigen Ihre Benutzer explizit aufrufen, eine Kostenlose Funktion, die Sie für Fragen Speicherverluste. normalerweise habe ich nur tun beide (release-Funktion + Doppel-check-in abschließen ...) ...
InformationsquelleAutor Hao Deng
Die finalize-Methode wird aufgerufen, nachdem der GC erkennt, dass das Objekt nicht mehr erreichbar, und bevor es tatsächlich Rückforderungen der Arbeitsspeicher, der von dem Objekt.
Wenn ein Objekt nie unerreichbar wird
finalize()
wird nie aufgerufen werden.Wenn die GC nicht läuft, dann
finalize()
kann nie aufgerufen werden. (Normalerweise ist der GC läuft nur, wenn die JVM beschließt, dass es wahrscheinlich genug Müll, um es lohnt sich.)Es kann mehr als einen GC-Zyklus vor dem GC bestimmt, dass ein bestimmtes Objekt nicht erreichbar ist. (Java-GCs sind in der Regel "Generationswechsel" Sammler ...)
Sobald der GC ein Objekt erkennt, ist nicht erreichbar-und beendbar, es ist Plätze auf einem finalization queue. Fertigstellung tritt in der Regel asynchron mit der normalen GC.
(Die JVM-spec eigentlich ermöglicht eine JVM zu nie laufen Finalizer ... vorausgesetzt, dass es nicht wieder den Speicherplatz der Objekte. Eine JVM implementiert wurde dieser Weg würde verkrüppelt werden /nutzlos, aber dieses Verhalten ist "erlaubt".)
Das Ergebnis ist, dass es unklug ist, auf die Sie sich verlassen Finalisierung Dinge zu tun, die durchgeführt werden müssen, um in einer bestimmten Zeit-Rahmen. Ist es "best practice" nicht, Sie überhaupt zu verwenden. Es sollte eine besser (also sicherer) Weg, das zu tun, was auch immer es ist Sie versuchen zu tun, in der
finalize()
Methode.Die einzige legitime Verwendung für die Fertigstellung ist zum bereinigen von Ressourcen, die im Zusammenhang mit Gegenständen, die verloren gegangen sind durch die Anwendung code. Selbst dann, sollten Sie versuchen zu schreiben, die den code der Anwendung, so dass Sie nicht verlieren die Objekte in den ersten Platz. (Zum Beispiel, verwenden Sie Java-7+ try-mit-Ressourcen, um sicherzustellen, dass
close()
immer genannt ...)Es ist schwer zu sagen, aber es gibt ein paar Möglichkeiten:
InformationsquelleAutor Stephen C
Da gibt es eine uncertainity in den Aufruf von finalize () - Methode durch die JVM (nicht sicher, ob finalize (), die überschrieben würden, werden ausgeführt oder nicht), zum Zweck des Studiums der bessere Weg, um zu beobachten, was passiert, wenn finalize() aufgerufen wird, ist die Kraft, die JVM aufrufen, die garbage collection von command
System.gc()
.Speziell finalize() wird aufgerufen, wenn ein Objekt nicht mehr in Gebrauch. Aber wenn wir versuchen, es zu nennen, indem es neue Objekte gibt es keine Gewissheit, in der seine Forderung. Also mit Sicherheit wir schaffen ein
null
Objektc
die offensichtlich keine Zukunft mehr nutzen, damit wir das Objekt sehenc
's finalize aufrufen.Beispiel
Ausgabe
Hinweis - Auch nach dem Bedrucken bis zu 70 und nach dem Objekt b nicht benutzt wird, in das Programm, es ist die Unsicherheit, die b deaktiviert ist oder nicht von JVM, da "Namens finalize-Methode in der Klasse Bike..." ist nicht gedruckt.
System.gc();
ist keine Garantie, dass die garbage collection ausgeführt werden.Es ist auch nicht gewährleistet, was Art der collection ausgeführt werden. Relevant, da die meisten Java-GCs sind "Generationen" - Sammler.
InformationsquelleAutor techloris_109
abschließen wird, drucken Sie die Zählung für die Klasse Kreation.
main
Wie Sie sehen können. Die folgende put-show der gc hat ausgeführt, der ersten Zeit, als die Klasse zu zählen ist 36.
InformationsquelleAutor user1623624
Haben gerungen mit finalizer-Methoden in letzter Zeit (in der Reihenfolge zu entsorgen connection-pools während der Prüfung), muss ich sagen, dass finalizer fehlen viele Dinge. Mit VisualVM zu beobachten, als auch die Verwendung von schwachen Referenzen zu verfolgen, die tatsächliche Interaktion, die ich gefunden, dass folgende Dinge sind wahr in einem Java-8-Umgebung (Oracle JDK, Ubuntu-15):
Letzten Gedanken
Finalize-Methode ist unzuverlässig, aber kann verwendet werden für eine einzige Sache. Sie können sicherstellen, dass ein Objekt geschlossen wurde oder entsorgt, bevor es wurde Müll gesammelt, wodurch es möglich ist, implementieren Sie einen fail-safe, wenn Objekte mit einer mehr komplizierten Lebens-Zyklus mit einem end-of-life Aktion richtig behandelt werden. Das ist der eine Grund, warum ich denken kann, ist es Wert, um um es zu überschreiben.
InformationsquelleAutor Martin Kersten
Einem Objekt wird für die Garbage collection freigegeben oder GC, wenn Ihr nicht erreichbar von allen live-threads oder statische refrences in anderen Worten kann man sagen, dass ein Objekt, wird für die garbage collection freigegeben, wenn alle seine Referenzen sind null. Zyklische Abhängigkeiten werden nicht gezählt als Referenz, so dass, wenn ein Objekt hat Eine Referenz von Objekt B und Objekt B hat eine Referenz von Objekt A und Sie haben keine andere live-Referenz dann die beiden Objekte A und B werden für die Garbage collection freigegeben.
In der Regel ein Objekt wird kommen für die garbage collection in Java auf folgende Fälle:
final
Bereich eines Objekts verwendet wird wiederholt, während eine langsame Berechnung, und das Objekt wird nie verwendet werden, nachdem, dass, würde das Objekt am Leben gehalten werden, bis der Letzte der die source-code-Anforderungen, die Feld, oder könnte der JIT-kopieren Sie das Spielfeld auf eine temporäre variable ist, und dann verlassen Sie das Objekt vor der Berechnung?ein Optimierer kann rewrite-code zu einem Formular, wo der Gegenstand ist nicht in Erster Linie erstellt; in diesem Fall kann es Finalisiert Recht, nachdem der Konstruktor fertig ist, es sei denn, die Synchronisation erzwingt eine Bestellung zwischen dem Objekt, der Nutzung und der finalizer.
In Fällen, in denen der JIT sehen können, alles, was jemals passieren wird, um ein Objekt zwischen seiner Kreation und Verzicht, ich sehe keinen Grund, für die JIT-Feuer der finalizer früh. Die eigentliche Frage wäre, was der code tun muss, um sicherzustellen, dass der finalizer kann nicht das Feuer innerhalb einer bestimmten Methode. In .NET gibt es ein
GC.KeepAlive()
Funktion, die nichts tut, außer Kraft zu der GC davon ausgehen, dass es vielleicht ein Objekt verwenden, aber ich kenne keine solche Funktion in Java. Könnte manvolatile
variable für diesen Zweck, aber mit Hilfe einer Variablen, die ausschließlich für einen solchen Zweck scheint verschwenderisch.Der JIT nicht Feuer Fertigstellung, es ist nur ordnet Sie den code, um eine Referenz, obwohl, es sein könnte nützlich, um direkt enqueue-die
FinalizerReference
, so, dass es nicht noch ein GC-Zyklus, um herauszufinden, dass es keine Hinweise. Die Synchronisation ist ausreichend, um sicherzustellen, eine passiert-bevor Beziehung; seit der Fertigstellung kann (ist eigentlich) laufen in einem anderen thread, es ist oft formal ohnehin notwendig. Java 9 ist, hinzufügen,Reference.reachabilityFence
...Wenn der JIT optimiert aus Objekt erstellen, das nur
Finalize
würde aufgerufen werden, überhaupt wäre, wenn der JIT produziert code, der hat so direkt. Würde die Synchronisation code in der Regel erwartet werden für Objekte, die nur erwarten, in einem einzigen thread? Wenn ein Objekt führt eine Aktion, die rückgängig gemacht werden muss, bevor es aufgegeben (z.B. das öffnen einer socket-Verbindung und der Erwerb von ausschließlichen Gebrauch für die Ressource am anderen Ende), dass ein finalizer schließen Sie die Verbindung, während der code ist immer noch mit der Steckdose wäre eine Katastrophe. Würde es normal sein, für code-Synchronisation...InformationsquelleAutor Tushar Trivedi
abschließen Methode ist nicht garantiert.Diese Methode wird aufgerufen, wenn das Objekt wird kommen für GC. Es gibt viele Situationen, in denen die Objekte möglicherweise nicht von der garbage Collection eingesammelt.
InformationsquelleAutor giri
Manchmal, wenn es zerstört wird, muss ein Objekt eine Aktion. Zum Beispiel, wenn ein Objekt ein nicht-java-resource wie z.B. ein Datei-handle oder eine schriftart, können Sie sicherstellen, dass diese Ressourcen freigegeben werden vor dem zerstören eines Objekts. Um solche Situationen zu verwalten, java bietet einen Mechanismus namens "finalisieren". Durch das finalisieren, können Sie definieren spezifische Aktionen, die auftreten, wenn ein Objekt entfernt wird von der garbage collector.
Einen finalizer hinzufügen einer Klasse definieren Sie einfach die finalize() Methode. Java execution time ruft diese Methode, wenn es darum geht, zu löschen, ein Objekt dieser Klasse. In der finalize - Methode() Sie die Aktionen bestimmen, die durchgeführt werden, bevor die Zerstörung eines Objekts.
Der garbage collector in regelmäßigen Abständen gesucht für Objekte, die nicht mehr sprechen, laufen-Zustand oder indirekt jedes andere Objekt mit Referenz. Bevor Sie ein asset veröffentlicht, die Java-Laufzeitumgebung ruft die finalize () - Methode auf das Objekt. Die finalize() Methode hat die folgende Allgemeine form:
Mit der geschützt Schlüsselwort, Zugang zu finalize() von code außerhalb seiner Klasse verhindert wird.
Es ist wichtig zu verstehen, dass finalize() genannt wird, nur kurz vor der garbage collection. Es wird nicht aufgerufen, wenn ein Objekt verlässt den Rahmen, zum Beispiel. Es heißt, Sie können nicht wissen, Wann oder ob finalize() ausgeführt werden. Als Ergebnis, das Programm muss andere Mittel bereitstellen, um die freie system-Ressourcen oder andere Ressourcen, die vom Objekt. Sollte man sich nicht verlassen auf finalize() für den normalen Betrieb des Programms.
InformationsquelleAutor Amarildo
Klasse, wo wir überschreiben der finalize-Methode
Die Chancen der finalize-Methode aufgerufen wird,
wenn der Speicher überlastet ist mit dump Objekte der gc-Aufruf finalize-Methode
laufen und die Konsole sehen, wo Sie nicht finden Sie die finalize-Methode aufgerufen wird, Häufig, wenn der Speicher immer überlastet dann die finalize-Methode wird aufgerufen werden.
InformationsquelleAutor pradeep
Quelle
InformationsquelleAutor JavaDev
finalize()
wird aufgerufen, kurz bevor die garbage-collection. Es wird nicht aufgerufen, wenn ein Objekt den Gültigkeitsbereich verlässt. Dies bedeutet, dass Sie nicht wissen, Wann oder sogar obfinalize()
ausgeführt werden.Beispiel:
Wenn Ihr Programm beenden, bevor der garbage collector auftreten, dann
finalize()
wird nicht ausgeführt. Daher sollte es als backup-Verfahren, um sicherzustellen, der richtige Umgang mit anderen Ressourcen, oder für spezielle Anwendungen, nicht als Mittel, die Ihr Programm verwendet in den normalen Betrieb.InformationsquelleAutor AyukNayr
Versuchen runiing dieses Programm zum besseren Verständnis
InformationsquelleAutor user3836455