.NET對象生命周期小結


參考資料

《C#與.NET4高級編程設計(第五版)》

MSDN

 

 

主要內容

new關鍵字

對象的代

垃圾回收過程

強制垃圾回收

Finalize與Dispsose方法

using語法

 

 

 

new關鍵字

new關鍵字返回的是一個指向堆上對象的引用,並非對象本身,該引用存儲在棧內。

new一個對象的過程:

image

 

 

對象的代

垃圾回收時,CLR並不會檢測托管堆上的每一個對象,這樣會花費大量時間。為了優化檢測過程,堆上的每一個對象都屬於“某代":

第0代:從沒被標記為回收的新分配的對象

第1代:上一次垃圾回收被標記為可回收但沒有被回收的對象

第2代:在一次以上的垃圾回收后沒有被回收的對象

代的設計思路是:對象在內存中存在的時間越長,他就更可能應該保留。

垃圾回收首先檢測第0代,當第0代回收部分對象后以后足夠內存空間為新對象分配,則幸存的標記為可回收未被回收的對象升級至第一代;如果第0代可回收對象全部回收后,內存空間仍不足以保存新對象,則檢測第1代對象,若得到了足夠內存空間,則第1代幸存對象將升至第2代;如果第1代可回收對象全部回收,內存仍不足,則檢測第2代對象,但第2代幸存的對象仍舊是第2代。

 

垃圾回收過程

CLR通過創建對象圖來檢測托管堆上的對象是否可被應用程序訪問,同一對象不會在對象圖上出現兩次,未在對象圖上出現的對象,說明應用程序已不可訪問該對象,它們將被從內存中清除。垃圾回收並不會回收所有不可訪問的對象,當有了足夠的內存空間提供給新對象,則停止回收。

 

強制垃圾回收

以下情況可能需要強制垃圾回收:1. 應用程序進入一段代碼,而這段代碼不希望被可能的垃圾回收中斷;2. 應用程序剛分配了很多對象,開發人員想要盡可能多地回收對象以獲得內存。

方式:

GC.Collect(); // 強制垃圾回收,同樣可傳入一個數值來指定要回收的最老的代

GC.WaitForPendingFinalizers(); // 等待垃圾回收結束

 

Finalize與Dispsose方法

Finalize方法

該方法的主要作用為保證.NET對象能在垃圾回收時清除非托管資源。

該方法為一個受保護的虛方法,無法直接調用,重寫該方法的唯一原因是,C#類通過PInvoke或者復雜的COM互操作任務使用了非托管資源。

要寫自定義的Finalize方法,不能用override進行重寫,要通過析構函數來寫,析構函數不接受訪問修飾符、參數和重載,函數名以 ~ 為前綴。

Class MyFinalizeSample

{

    ~MyFinalizeSample()

    {

        // 清理非托管資源

    }

}

Finalize可以保證對象可以清楚非托管資源,但它的效率非常低,因為在終結這個對象時,至少會進行兩次垃圾回收。原因為:當在托管堆上分配對象時,運行庫會確定該對象是否包含自定義的Finalize方法,如果包含,這個對象會被標記為“可終結”對象,並在一個由垃圾回收器維護的“終結隊列”中保存一個指向該對象的指針。當垃圾回收器確定了釋放一個對象的時間時,它會檢查“終結隊列”中的每一個指針,並將對象從堆上復制到另一個叫做“終結可達表”的托管結構上,下一次垃圾回收時將產生另一個線程來為每一個“終結可達表”上的對象調用Finalize方法。

 

Dispose方法

該方法不同於Finalize,它需要顯式調用,如果一個類實現了IDisposable接口,就可以顯式地調用對象的Dispose方法來釋放資源。垃圾回收器本身不支持IDisposable接口,所以不會調用Dispose方法。如果一個類需要Finalize方法,最好讓它實現IDisposable接口,調用對象的Dispose方法來釋放資源,這樣可以避免Finalize方法帶來的性能開銷。

當一個類定義了析構函數,如果我們忘了調用Dispose方法,垃圾回收器也會幫我們回收非托管資源,如果我們調用了Dispose方法,可以再調用GC.SuppressFinalize(this)方法來跳過垃圾回收器調用Finalize的過程,所以,這兩種釋放資源的方式可以結合使用。

 

 

using關鍵字

如果一個類實現了IDisposable接口,我們可以簡單的用using語法來創建一個對象:

using( Test test = new Test() )

{

}

當代碼塊執行結束時或者在執行過程中出現異常時,都會自動調用該對象的Dispose方法以確保資源的釋放。簡單、方便!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM