395 Stimmen

Warum würden Sie jemals finalize() implementieren?

Ich habe viele Fragen von Anfängern in Java zu finalize() durchgelesen und finde es irgendwie verwirrend, dass niemand wirklich klargestellt hat, dass finalize() kein zuverlässiger Weg ist, Ressourcen aufzuräumen. Ich habe gesehen, wie jemand kommentiert hat, dass sie es verwenden, um Verbindungen zu bereinigen, was wirklich beängstigend ist, da der einzige Weg, um so nah wie möglich an eine Garantie zu kommen, dass eine Verbindung geschlossen ist, ist, try (catch) finally zu implementieren.

Ich wurde nicht in Informatik ausgebildet, aber ich programmiere seit fast einem Jahrzehnt professionell in Java und ich habe noch nie jemanden gesehen, der finalize() in einem Produktionssystem implementiert hat. Das bedeutet immer noch nicht, dass es keine Verwendung hat, oder dass die Leute, mit denen ich gearbeitet habe, es richtig gemacht haben.

Also frage ich mich, welche Anwendungsfälle es für die Implementierung von finalize() gibt, die nicht zuverlässiger über einen anderen Prozess oder eine andere Syntax innerhalb der Sprache behandelt werden können?

Bitte geben Sie spezifische Szenarien oder Ihre Erfahrung an, einfach das Java-Lehrbuch zu wiederholen oder die beabsichtigte Verwendung von finalize reicht nicht aus, da dies nicht der Zweck dieser Frage ist.

0 Stimmen

HI finalize () Methode sehr gut hier erklärt howtodoinjava.com/2012/10/31/…

5 Stimmen

Die meisten Anwendungs- und Bibliothekscodes werden finalize() niemals verwenden. Allerdings tut Plattformbibliothekcode, wie z.B. SocketInputStream, der native Ressourcen im Namen des Aufrufers verwaltet, dies, um das Risiko von Ressourcenlecks zu minimieren (oder verwendet äquivalente Mechanismen wie PhantomReference, die später hinzugefügt wurden). Daher werden sie im Ökosystem benötigt, obwohl 99,9999% der Entwickler niemals einen schreiben werden.

4 Stimmen

Aktualisierung: finalize ist ab Java 9 veraltet. Siehe die Frage, Warum ist die finalize() Methode in Java 9 veraltet?.

5voto

Steven M. Cherry Punkte 1335

Seien Sie vorsichtig, was Sie in einem finalize() tun. Besonders wenn Sie es für Dinge wie das Aufrufen von close() verwenden, um sicherzustellen, dass Ressourcen aufgeräumt werden. Wir sind auf mehrere Situationen gestoßen, in denen wir JNI-Bibliotheken in den laufenden Java-Code eingebunden hatten, und in allen Fällen, in denen wir finalize() verwendet haben, um JNI-Methoden aufzurufen, trat eine sehr schlechte Java-Heap-Korruption auf. Die Korruption wurde nicht durch den zugrunde liegenden JNI-Code selbst verursacht, alle Speichertraces waren in den nativen Bibliotheken in Ordnung. Es lag einfach daran, dass wir überhaupt JNI-Methoden aus dem finalize() aufgerufen haben.

Dies war bei einer JDK 1.5, die immer noch weit verbreitet ist.

Wir haben erst viel später festgestellt, dass etwas schief gelaufen ist, aber am Ende war der Schuldige immer die finalize()-Methode, die JNI-Aufrufe verwendet hat.

0 Stimmen

Wie haben Sie es geschafft, den im JNI allokierten Speicher freizugeben?

4voto

Hmmm, ich habe es einmal benutzt, um Objekte aufzuräumen, die nicht an einen vorhandenen Pool zurückgegeben wurden.

Sie wurden viel verschoben, sodass es unmöglich war zu sagen, wann sie sicher in den Pool zurückgegeben werden konnten. Das Problem war, dass es eine enorme Strafe während der Müllsammlung eingeführt hat, die weit größer war als jede Einsparung durch das Poolen der Objekte. Es war etwa einen Monat lang in Produktion, bevor ich den gesamten Pool herausgerissen habe, alles dynamisch gemacht habe und damit fertig war.

3voto

John Meagher Punkte 21478

Beim Schreiben von Code, der von anderen Entwicklern verwendet wird und eine Art "Aufräum"-Methode erfordert, um Ressourcen freizugeben, kann es vorkommen, dass diese anderen Entwickler vergessen, Ihre Aufräum- (oder Schließen- oder Zerstörungs-) Methode aufzurufen. Um mögliche Ressourcenlecks zu vermeiden, können Sie im finalize-Verfahren überprüfen, ob die Methode aufgerufen wurde, und wenn nicht, sie selbst aufrufen.

Viele Datenbanktreiber tun dies in ihren Statement- und Connection-Implementierungen, um ein wenig Sicherheit gegenüber Entwicklern zu bieten, die vergessen, sie zu schließen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X