Newsgroup Archiv - Beiträge

auf www.Bastie.de

finalize() wird nie aufgerufen?

Frager: Thomas Rachel vom Samstag, 27. Januar 2001
Hallo,
ich habe in Objekt geschrieben, welches beim Zerstört werden noch etwas machen soll. Leider wird aber der Finalizer nie aufgerufen. (Beispiel siehe unten).
Eigentlich sollte finalize() doch aufgerufen werden, sobald das Objekt nicht mehr zugreifbar ist, d.h.
im Falle von new obj() direkt,
im Falle von new obj().print() nach dem print() und
im Falle von "obj thatfuck=new obj(); thatfuck=new obj();" nach der 2. Zuweisung.
Was übersehe ich?
TIA,
Thoma$
1. Antwort: Markus Junginger vom Samstag, 27. Januar 2001
So weit ich weiß, ist es nicht garantiert, dass finialize aufgerufen wird (strange!?). Könntest allerdings die zwei Aufrufe
System.gc();
und System.runFinalization();
probieren.
Jetzt hängt's von der VM ab was sie macht...
Gibt noch zwei andere Möglichkeiten:
System.runFinalizersOnExit(boolean value) ;
-> ist aber veraltet und es gibt afaik keinen Ersatz
Ab 1.3 gibt's addShutdownHook(Thread hook) in Runtime. Hiermit könntest du eigene Aufräum-Rountinen implementieren....
Die finalize() Methode ist ja total vermurkst... Oder habe ich etwas übersehen?
Markus Junginger
1.1 Antwort: Thomas Rachel vom Samstag, 27. Januar 2001
[...]
2. Antwort: Markus Junginger vom Samstag, 27. Januar 2001
Laut http://java.sun.com/docs/books/jls/second_edition/html/execution.doc.html#44748 sollte es theoretisch funktionieren...

2.1. Antwort: Thomas Rachel vom Samstag, 27. Januar 2001
[...]
3. Antwort: Michael Ruflin vom Samstag, 27. Januar 2001
[...]
3.1. Antwort: Thomas Rachel vom Samstag, 27. Januar 2001
[...]
4. Antwort: Ruediger Gubler vom Samstag, 27. Januar 2001
finalize() wird aufgerufen, wenn der GarbageCollector den Speicher aufräumt! Dies macht nur wenn wirklich Bedarf ist. Es kann sein, dass isch dein Programm und die VM beendet ohne dass der GC anläuft!
Rüdiger
5. Antwort: bernd hohmann vom Samstag, 27. Januar 2001
> ich habe in Objekt geschrieben, welches beim Zerstört-werden noch etwas
> machen soll. Leider wird aber der Finalizer nie aufgerufen. (Beispiel
> siehe unten).
doch, und zwar in dem moment, wo das objekt komplett entfernt wird.
ob und wann das jemals passiert hängt von den 'launen' der garbage collection (GC) ab.
dh. das .finalize() wird erst dann durchlaufen, wenn die GC das objekt aus dem speicher entfernt - das kann unter umständen dauern weil gerne zuerst die sachen entfernt werden, die viel speicher brauchen.
und ich weiss auch nicht, ob die JVM .finalize() aufruft wenn sie aus performancegründen ein objekt wiederverwendet (dazu stelle ich gleich mal eine frage hier in der gruppe).
meiner erfahrung ist .finalize() eine geschichte, auf die man sich je nach JVM nur dann verlassen kann, wenn spätestens beim beenden des programms alle objekte 'finalisiert' werden.
bernd
5.1. Antwort: Thomas Rachel vom Sonntag, 28. Januar 2001
[...]
> doch, und zwar in dem moment, wo das objekt komplett entfernt wird.
Bei dem genannten Programm nie, auch nicht bei Programmende. Zumindest nicht mit der Sun-JRE 1.3.0.
[...]
Thoma$
5.1.1. Antwort: bernd hohmann vom Sonntag, 28. Januar 2001
[...]
> Bei dem genannten Programm nie, auch nicht bei Programmende. Zumindest
> nicht mit der Sun-JRE 1.3.0.
bei 1.1.x gab es den schalter .runFinalizersOnExit(), welcher in den nachfolgenden versionen abgeschafft und durch einen anzustossenden tread ersetzt wurde (der natürlich nicht die internen informationen hat wie die JVM und daher doch so einige änderungen in den programmen verursacht).
[...]
bernd
5.1.1.1. Antwort: Markus Junginger vom Sonntag, 28. Januar 2001
[...]
Aber dieser Thread ist nicht zuverläßig, oder? Kann man ihn explizit anstoßen oder funktioniert er über System.runFinalization?
Mich würde schon interessieren, ob finalize() überhaupt noch einen Sinn macht...

5.1.1.1.1. Antwort: Markus Junginger vom Sonntag, 28. Januar 2001
[...]
> Aber dieser Thread ist nicht zuverläßig, oder? Kann man ihn explizit
> anstoßen oder funktioniert er über System.runFinalization?
das weiss ich nicht da wir im moment keine 1.3er version im einsatz haben. aber vermutlich ist das ganze so zuverlässig wie .runFinalizersOnExit(true) ;-)
> Mich würde schon interessieren, ob finalize() überhaupt noch einen
> Sinn macht...
aber natürlich. wir haben in etwa folgende konstruktion in der parentklasse einer jeden applikation oder toolbox:
public void dispose() {
   if (blnDisposed) return;
   blnDisposed = true;
   // housekeeping
}
public finalize() {
   if (blnDisposed) return;
   System.out.println("dispose by finalize:"+toString());
   dispose();
}

da geht es in der hauptsache um das explizite schliessen von sockets, datenbanksachen, austragen aus protokollen und ähnliches.
und weil man gerne mal den aufruf des internen dispose() vergisst, gibt es einen hinweis, wenn das der finalizer macht damit man eine chance hat, dass zu kennen und im nächsten relase auszubauen.
bernd
Anmerkung:
Der Thead ging noch weiter wich jedoch weiter vom hier gewollten Thema ab, so dass auf die weitere Darstellung verzichtet wird. Mit dem Java SDK 1.3 wurde auch eine Möglichkeit eingeführt, Abschlussarbeiten garantiert ausführen zu lassen. Wie? schauen Sie doch mal in den How To -Bereich von Java...

zur Übersicht

all rights reserved © Bastie - Sebastian Ritter @: w³: http://www.Bastie.de
Diese Seite ist Bestandteil der Internetpräsenz unter http://www.Bastie.de


Java Cobol Software Resourcen Service Links Über mich Zum Gästebuch Forum