垃圾收收集器(GC)只知道釋放由new關鍵字分配的記憶體,所以不知道如何釋放物件的“特殊”記憶體。為了解決這個問題,Java提供了一個名為:finalize()的方法,可為我們的類定義它。
理想情況下finalize()方法的工作原理是這樣:一旦CG準備好釋放物件佔用的記憶體空間,它首先呼叫finalize()方法,而且只有在下一次的垃圾收集過程中,才會真正回收物件的記憶體。
GC != Destructor,垃圾收集器並不等於破壞器。
為強制進行收尾工作(執行除釋放物件儲存空間之外的其它某種形式的清除工作),可先呼叫System.gc(),再呼叫System.runFinalization()。這樣可清除到目前為止沒有使用的所有物件。這樣做一個稍顯奇怪的地方是在呼叫runFinalization()之前呼叫gc(),這看起來似乎與Sun公司的文件說明有些牴觸,它宣稱首先執行收尾模組,再釋放儲存空間。然而,若在這裡首先呼叫runFinalization(),再呼叫gc(),收尾模組根本不會執行。
針對所有物件,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."); } } }