finalize

finalize

finalize-方法名。Java技術允許使用finalize()方法在垃圾收集器將對象從內存中清除出去之前做必要的清理工作。

介紹


這個方法是由垃圾收集器在確定這個對象沒有被引用時對這個對象調用的。它是在Object類中定義的,因此所有的類都繼承了它。子類覆蓋finalize()方法以整理系統資源或者執行其他清理工作。finalize()方法是在垃圾收集器刪除對象之前被自動調用的。
垃圾收集器只知道釋放那些由new分配的內存,所以不知道如何釋放對象的“特殊”內存。為解決這個問題,Java提供了一個名為finalize()的方法,它的工作原理應該是這樣的:一旦垃圾收集器準備好釋放對象佔用的存儲空間,它首先調用finalize(),而且只有在下一次垃圾收集過程中,才會真正回收對象的內存。所以如果使用finalize(),就可以在垃圾收集期間進行一些重要的清除或清掃工作(如關閉流等操作)。但JVM(Java虛擬機)不保證此方法總被調用。
Finalize操作具有下列限制:
垃圾回收過程中執行終結器的準確時間是不確定的。不保證資源在任何特定的時間都能釋放,除非調用Close方法或Dispose方法。
即使一個對象引用另一個對象,也不能保證兩個對象的終結器以任何特定的順序運行。即,如果對象A具有對對象B的引用,並且兩者都有終結器,則當對象A的終結器啟動時,對象B可能已經終結了。
運行終結器的線程是未指定的。
在下面的異常情況下,Finalize方法可能不會運行完成或可能根本不運行:
另一個終結器無限期地阻止(進入無限循環,試圖獲取永遠無法獲取的鎖,諸如此類)。由於運行時試圖運行終結器來完成,所以如果一個終結器無限期地阻止,則可能不會調用其他終結器。
進程終止,但不給運行時提供清理的機會。在這種情況下,運行時的第一個進程終止通知是DLL_PROCESS_DETACH通知。
在關閉過程中,只有當可終結對象的數目繼續減少時,運行時才繼續Finalize對象。
如果Finalize或Finalize的重寫引發異常,並且運行庫並非寄宿在重寫默認策略的應用程序中,則運行庫將終止進程,並且不執行任何活動的try-finally塊或終結器。如果終結器無法釋放或銷毀資源,此行為可以確保進程完整性。
給實現者的說明默認情況下,Object.Finalize不執行任何操作。只有在必要時才必須由派生類重寫它,因為如果必須運行Finalize操作,垃圾回收過程中的回收往往需要長得多的時間。如果Object保存了對任何資源的引用,則Finalize必須由派生類重寫,以便在垃圾回收過程中,在放棄Object之前釋放這些資源。當類型使用文件句柄或資料庫連接這類在回收使用託管對象時必須釋放的非託管資源時,該類型必須實現Finalize。有關輔助和具有更多控制的資源處置方式,請參見IDisposable介面。Finalize可以採取任何操作,包括在垃圾回收過程中清理了對象后使對象復活(即,使對象再次可訪問)。但是,對象只能復活一次;在垃圾回收過程中,不能對復活對象調用Finalize。
析構函數是執行清理操作的C#機制。析構函數提供了適當的保護措施,如自動調用基類型的析構函數。在C#代碼中,不能調用或重寫Object.Finalize。

示例


package Initialization;
class Tank{
int howFull=0;
Tank() {this(0);}
Tank(int fullness){
howFull=fullness;
}
void sayHowFull(){
if(howFull==0)
System.out.println("Tank is empty!");
else
System.out.println("Tank filling status:"+howFull);
}
void empty(){
howFull=0;
}
protected void finalize(){
if(howFull!=0){
System.out.println("Error:Tank not empty."+this.howFull);
}
//Normally,you'll also do this:
//Super.finalize();//call the base-class version
}
}
public class TankTest{
public static void main(String[]args){
Tank tank1=new Tank();
Tank tank2=new Tank(3);
Tank tank3=new Tank(5);
tank2.empty();
//Drop the reference,forget to cleanup:
new Tank(6);
new Tank(7);
System.out.println("Check tanks:");
System.out.println("tank1:");
tank1.sayHowFull();
System.out.println("tank2:");
tank2.sayHowFull();
System.out.println("tank3");
tank3.sayHowFull();
System.out.println("first forced gc()");
System.gc();
System.out.println("try deprecated runFinalizerOnExit(true)");
System.runFinalizersOnExit(true);
System.out.println("last forced gc():");
System.gc();
}
}