在.net 編程環境中,系統的資源分為託管資源和非託管資源。
對於託管的資源的回收工作,是不需要人工幹預回收的,而且你也無法幹預他們的回收,所能夠做的
只是瞭解.net CLR如何做這些操作。也就是說對於您的應用程式建立的大多數對象,可以依靠 .NET
Framework 的記憶體回收行程隱式地執行所有必要的記憶體管理工作。
對於非託管資源,您在應用程式中使用完這些非託管資源之後,必須顯示的釋放他們,例如
System.IO.StreamReader的一個檔案對象,必須顯示的調用對象的Close()方法關閉它,否則會佔用系統
的記憶體和資源,而且可能會出現意想不到的錯誤。
我想說到這裡,一定要清楚什麼是託管資源,什麼是非託管資源了?
最常見的一類非託管資源就是封裝作業系統資源的對象,例如檔案,視窗或網路連接,對於這類資源
雖然記憶體回收行程可以跟蹤封裝非託管資源的對象的生存期,但它不瞭解具體如何清理這些資源。還好.net
Framework提供了Finalize()方法,它允許在記憶體回收行程回收該類資源時,適當的清理非託管資源。如果
在MSDN Library 中搜尋Finalize將會發現很多類似的主題,這裡列舉幾種常見的非託管資源:
ApplicationContext,Brush,Component,ComponentDesigner,Container,Context,Cursor,FileStream,Fon
t,Icon,Image,Matrix,Object,OdbcDataReader,OleDBDataReader,Pen,Regex,Socket,StreamWriter,Time
r,Tooltip 等等資源。可能在使用的時候很多都沒有注意到!
關於託管資源,就不用說了撒,像簡單的int,string,float,DateTime等等,.net中超過80%的資源都是托
管資源。
非託管資源如何釋放,.NET Framework 提供 Object.Finalize 方法,它允許對象在記憶體回收行程回收該對
象使用的記憶體時適當清理其非託管資源。預設情況下,Finalize 方法不執行任何操作。預設情況下,
Finalize 方法不執行任何操作。如果您要讓記憶體回收行程在回收對象的記憶體之前對對象執行清理操作,您
必須在類中重寫 Finalize 方法。然而大家都可以發現在實際的編程中根本無法override方法Finalize
(),在C#中,可以通過解構函式自動產生 Finalize 方法和對基類的 Finalize 方法的調用。
例如:
~MyClass()
{
// Perform some cleanup operations here.
}
該代碼隱式翻譯為下面的代碼。
protected override void Finalize()
{
try
{
// Perform some cleanup operations here.
}
finally
{
base.Finalize();
}
}
但是,在編程中,並不建議進行override方法Finalize(),因為,實現 Finalize 方法或解構函式對效能
可能會有負面影響。一個簡單的理由如下:用 Finalize 方法回收對象使用的記憶體需要至少兩次記憶體回收
,當記憶體回收行程回收時,它只回收沒有終結器(Finalize方法)的不可訪問的記憶體,這時他不能回收具有終
結器(Finalize方法)的不可以訪問的記憶體。它改為將這些對象的項從終止隊列中移除並將他們放置在標記
為“準備終止”的對象列表中,該列表中的項指向託管堆中準備被調用其終止代碼的對象,下次記憶體回收
器進行回收時,就回收並釋放了這些記憶體。