metoda finalize()

0

Witam.

Dopiero uczę się JAVY z ksiązki Thinking in JAVA B. Eckela. Mam pytanie dot. sprzątania, a dokładniej metody finalize().

Wklepałem przykład ze str. 160 tejże książki:

package nauka.rozdzial5;


class Book{
    boolean checkedOut = false;

    Book(boolean checkOut)
    {
        checkedOut = checkOut;
    }
    void checkIn()
    {
        checkedOut = false;
    }
    protected void finalize()
    {
        System.out.println("wszedł do finalize();");
        if(checkedOut){
            System.out.println("Błąd: w obiegu");
            //Normalnie użyłbyś również tego:
            //super.finalize(); //Wywołanie wersji bazowej
        }
    }
}

public class TerminationCondition {
    
    public static void main(String[] args){
        
        Book novel = new Book(true);
        //właściwe "sprzątanie":
        novel.checkIn();
        //Porzucenie referencji, przeoczenie sprzątania:
        new Book(true);
        //Wymuszenie odśmiecenia pamięci i finalizacji:
        System.gc();
    }
    
}

i teraz moje pytanie. Zgodnie z tym, co sugeruje autor na wyjściu powinien pojawić się komunikat "Błąd: w obiegu". Jest to dla mnie jasne, ponieważ w ostatniej linijce metody main wywołuję odśmiecacz, który z kolei wywołuje finalize(). Problem polega na tym, że po przekompilowaniu przykładu nie widzę tego komunikatu. Na początku finalize() dodałem komunikat "wszedł do finalize();" i jego też nie widzę, więc od razu widać, że ta metoda się nie wykonuje.

Co ciekawe, kiedy debuguję kod, to finalize ładnie i zgodnie z moim oczekiwaniem się wykonuje.
Moja prośba do Was - czy ktoś możę mi wytłumaczyć dlaczego tak się dzieje? Dlaczego tylko w trybie debug uruchamia się System.gc() i finalize()?

Z góry dziękuję za odpowiedź.

P.S. Jeśłi to ma znaczenie, to używam Netbeans 7.2 dla x64

0

Wszystko jest ok: http://ideone.com/NO4ao
to z tej linijki "new Book(true)" otrzymujesz ten komunikat "Błąd: w obiegu", bo z tym argumentem nadajesz polu checkedOut wartość true.

1

System.gc() to tylko sugestia dla JVM, żeby odpalić odśmiecanie. W ogólności odśmiecanie jest niedeterministyczne, w tym sensie, że nie da się przewidzieć kiedy obiekt zostanie odśmiecony.

Nawet w Javadocach masz:

Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse.

0

Tak jak pisałem wcześniej u mnie oba komunikaty się nie pojawiają :(

Dopiero w trybie debug widzę:

debug:
wszedł do finalize();
Błąd: w obiegu

Kiedy robię zwykły run file nic się nie wyświetla, stąd wnioskuję, że metoda finalize() nie jest wykonywana.

@Edit:

Wibowit dzięki za odpowiedź. Jeśli dobrze zrozumiałem System.gc() może, ale nie musi być odpalone (w moim wypadku nie było) jeśli pamięci jest jeszcze dużo.

1 użytkowników online, w tym zalogowanych: 0, gości: 1