Java清除:收尾和垃圾收集

垃圾收收集器(GC)只知道釋放由new關鍵字分配的內存,因此不知道如何釋放對象的「特殊」內存。爲了解決這個問題,Java提供了一個名爲:finalize()的方法,可爲咱們的類定義它。
spa

理想狀況下finalize()方法的工做原理是這樣:一旦CG準備好釋放對象佔用的內存空間,它首先調用finalize()方法,並且只有在下一次的垃圾收集過程當中,纔會真正回收對象的內存。code

GC != Destructor,垃圾收集器並不等於破壞器。對象

爲強制進行收尾工做(執行除釋放對象存儲空間以外的其它某種形式的清除工做),可先調用System.gc(),再調用System.runFinalization()這樣可清除到目前爲止沒有使用的全部對象。這樣作一個稍顯奇怪的地方是在調用runFinalization()以前調用gc(),這看起來彷佛與Sun公司的文檔說明有些抵觸,它宣稱首先運行收尾模塊,再釋放存儲空間。然而,若在這裏首先調用runFinalization(),再調用gc(),收尾模塊根本不會執行。blog

針對全部對象,Java1.1有時之因此會默認爲跳過收尾工做,是因爲它認爲這樣作的開銷太大。無論用哪一種方法強制進行垃圾收集,均可能注意到比沒有額外收尾工做時較長的時間延遲內存

finalize()最有用處的地方之一是觀察垃圾收集的過程文檔

public class Garbage {
    public static void main(String[] args) {

        while (!Chair.f) {
            new Chair();
            new String("To take up space");
        }

        System.out.println("After all Chairs have been created:\n" + "total created = " + Chair.created + ", total finalized = " + Chair.finalized);

        System.out.println("gc():");
        System.gc();
        System.out.println("runFinalization():");
        System.runFinalization();

        System.out.println("bye!");
    }
}

public class Chair {
    static boolean gcrun = false;
    static boolean f = false;
    static int created = 0;
    static int finalized = 0;
    int i;

    public Chair() {
        i = ++created;
        if (created == 47){
            System.out.println("Created 47");
        }
    }

    protected void finalize(){
        if (!gcrun){
            gcrun = true;
            System.out.println("Beginning to finalize after chairs been created.");
            System.out.println("i=" + i);
            System.out.println("created=" + created);
        }
        if (i == 47){
            System.out.println("Finalize chair #47,setting flag to stop chair creation.");
            f = true;
        }
        finalized++;
        if (finalized >= created){
            System.out.println("All finalized.");
        }
    }
}
相關文章
相關標籤/搜索