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 對象。

如果 FinalizeFinalize 的重寫引發異常,並且運行庫並非寄宿在重寫默認策略的應用程式中,則運行庫將終止進程,並且不執行任何活動的 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();

}

}

相關詞條

相關搜尋

熱門詞條

聯絡我們