垃圾收收集器(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."); } } }