Warum wird finalize() nicht aufgerufen?



  • Frage: Wie sieht das eigentlich mit Destruktoren aus?? Wenn ich nen static counter hab, wieviel Objekte ich mit Konstruktoren erstelle, kann ich mich darauf verlassen, dass der Destruktor brav aufgerufen wird und meinen Zähler verringert, wenn ich alle Referenzen auf das Objekt lösche?? (wahrscheinlich nicht)



  • Optimizer: Es gibt in Java keine Destruktoren wie in C++. Es gibt nicht das Konzept, dass irgendwas passiert, wenn eine Variable aus dem Scope fällt oder eine Referenz umgebogen wird, wie bei C++-Smartpointern. Alle Referenzen sind dumme Pointer, und den Rest macht der GC, wenn er sich dazu bequemen kann. Dabei ruft er zwar Finalizer auf (so vorhanden), aber das ist, wie schon gesagt wurde, am Programmende nicht garantiert.



  • @Optimizer:
    In Java gibt es eben keine Destructoren.

    finalize() ist eine Methode die jedes Object hat. Diese Funktion wird vom Garbage-Collector aufgerufen, bevor er das Object löscht.
    Dieser löscht jedoch die Objecte nicht sofort, wenn sie nicht mehr referenziert werden, sondern "irgendwann". (Wenn er halt dazu kommt)

    Wenn man finalize() überschreibt kann man es etwa als Destruktor ansehen, wobei eben nicht garantiert ist, zu welchem Zeitpunkt er aufgerufen wird.

    @Gregor
    Eben um zu vermeiden, dass er Benutzer der Klasse ein explizietes obj.close()
    machen muss.
    In meinem Fall, sollte die Klasse etwas in eine Datei schreiben, was sie im Kontruktor dann wieder ausliest.

    @Terminte
    ShutdownHooks hab ich mir auch schon angeschaut, jedoch kann mir nicht vorstellen, wie man in der eigenen Klasse einen Shutdownhook auf den eigenen
    "Destruktor" setzen soll.

    Lange Rede kurzer Sinn:
    finalize() ist ziemlich nutzlos, da der Aufruf nicht garantiert ist,
    und man muss eine .close()-Methode anbieten.
    Java ist eben nicht c++ 😉



  • @Tendor: ... und das ist auch gut so.

    SCNR



  • Da widerspreche ich bestimmt nicht. Ich bin nur etwas erstaunt, wie man jetzt z.B. bequem einen Objektzähler programmieren soll.



  • Was soll man denn mit einem Objektzähler?


  • Mod

    BTW: Ohne es zu wissen, vermute ich fast, dass so ein "Objekte zählen" ab Java 1.5 sehr einfach wird. Ab da kommt die neue Management-API. Ich vermute, dass die soetwas generell kann.



  • hi

    um einen shutdown hook einzubinden must du einen Thread inplementieren. das geht wenn ich mich recht erinnere einmal über der implementieren des Interfaces runabel oder das ableiten von Thread

    beim interface ist das recht einfach. du implementiertst die metode run() wenn micht nicht alles teuscht. Die wird ausgefürt wenn der shutdown ausgelöst wird. da run() ja im gleichen obj implementiert wird wie der rest deines obj hast du volle zugriff drauf. und kannst somit die datei schliessen und den rest der daten speichern. Im konstruktor meldest du das objekt an, im finaliser trägst du in wieder aus. zu beachten ist, das die verwaltung etwas komplexer wird. "ist die datei offen dann eintragen des shutdown hooks(bevor die datei geöffnet wird)." "wird die datei geschlossen, alles sichern, datei schliesen und dann shutownhook abmelden." sicherzutsellen ist dann auch, das nichts passiert wenn die datei 2 mal geschlossen wird. bzw ist dies zuverhindern.

    wenn du von Thread ableitest, must du dem thread erst dine klasse bekantmachen.
    Deine klasse stellt entsprechende schnittstellen zur verfügung damit der Thread das speichern der daten einleiten kann. verhalten dan so änlich wie oben.

    Aufpassen dadlocks und schleiffen können die VM blokieren.

    gruss michael



  • Meinst du so:

    public class MyObject implements Runnable {
    	MyObject() {
    		Runtime.getRuntime().addShutdownHook(new Thread(this));
    	}
    
    	public void run() {
    		this.close();
    	}
    
    	private void close() {
    		System.out.println("MyObject.close");
    	}
    }
    

    Hast recht, das geht, aber ich weiß nicht... Ich denke das ist nicht besonders toller Stil. Dann doch lieber public void close(), was dann eben der Nutzer aufrufen muss.

    (Vielleicht geht es ja in Java 1.5 wieder ohne Tricksereien, hab mir die neuen Features noch nicht so genau angesehen)



  • Hi

    Ja so in etwa hab ich mir das vorgestellt.

    gruss Michael


Anmelden zum Antworten