c#資源釋放及dispose、close和析構方法
c#中標準dispose模式的實現」
一:什麼是資源
在開始本文前,需要一些準備知識。首先要提出「什麼是資源」。在clr出來之後,windows系統資源開始分為「非託管資源」和「託管資源」。
託管資源是指:由clr管理分配和釋放的資源,即由clr裡new出來的物件。
其次再來講,資源的釋放方式。
非託管資源:需要顯式釋放的,也即需要你寫**釋放;
託管資源:並不需要顯式釋放,但是如果引用型別本身含有非託管資源,則需要進行現實釋放;
二:顯式釋放的c#實現
顯式釋放的c#實現,由c#語法支援的有:
1:實現idisposable介面的dispose方法;
2:析構方法(終結器);
不由c#語法支援,但是約定支援的顯式釋放是:
3:提供顯示釋放方法,比如常用的close方法;
三:dispose、close和析構方法異同點
但是,還需要區分這3種方式的異同點。首先,你無法呼叫析構方法。析構方法是由垃圾**機制進行呼叫的。換句話來說,就是你不知道析構方法被呼叫的時機。嚴格意義上來說,它只是作為資源釋放的乙個補救措施。
資源釋放的乙個正確的措施是為型別實現idisposable介面的dispose。當你需要釋放型別的資源的時候,應該顯示的呼叫dipose方法。當然,這裡還有乙個c#的語法糖,就是使用using程式塊,在離開using程式塊的時候,clr會自動呼叫型別所建立物件的dipose方法。
可能有人會問道,既然可以通過dispose方法的方式來進行資源的釋放,為什麼有些型別還需要提供乙個close方法。這裡面的區別,或者說約定在於,如果你仔細觀察這些型別:他們基本都只公開了close方法,他們都實現了idisposable,但都隱藏了dispose方法。以socket這個類為例,它:
1:提供public void close()
public void close()
2:提供顯式void idisposable.dispose()
void idisposable.dispose()
3:提供protected virtual void dispose(bool disposing)。真正的資源釋放的**放在這裡。
所以理論上來將,提供close方法最終還是使用的dispose方法,之所以這麼做,是因為這些型別出於顯式實現idisposable的因素,在呼叫這些dispose方法的時候,必須完成一次轉型,如:
((idisposable)new a()).dispose();
為了避免轉型,同時也為了避免不熟悉c#語法的開發人員更直觀的釋放資源,提供了close方法。
在上文的例子中,你可能已經注意到idisposable.dispose這個方法中,包含一句:
gc.suppressfinalize(this);
這是告訴clr,在進行垃圾**的時候,不用再繼續呼叫析構方法(終結器)了。是的,因為你已經手動釋放資源了。這也從另乙個方面驗證了析構方法只是作為資源釋放的補救機制。因為假設你忘記close或者dispose了,clr會在垃圾**的時候為你做這件事。檢視socket的析構函式,你會很好的理解這一點。
~socket()
是的,析構方法呼叫的也是dispose。
備註1:本文帶來幾個爭論
1:託管資源本身是否需要顯式釋放。答案顯然是:不需要;
2:如果引用型別物件不再需要,是否需要顯式=null;答案是:即使不這樣做,gc也會進行垃圾**。
3:將託管資源分為引用型別資源和值型別資源這種分類方法是有問題的,或者說是錯誤的。正確的分類法應該是棧資源和堆資源。執行緒棧中存放的是方法的實參和方法內部的區域性變數。堆上存放的是型別物件本身及物件的兩個額外成員:型別物件指標和同步塊索引。
4:dispose方法本身是用來讓你放置資源清理**的。顯然,乙個空方法並不代表清理工作本身,真正執行清理工作的是你具體的**。
備註2:推薦dipose模式實現
如:基類
**class classshoulddisposebase : idisposable
protected virtual void dispose(bool disposing)
}~classshoulddisposebase()
}子類:
**class classshoulddispose: classshoulddisposebase
else
}public void close()
}
C 資源釋放
c 記憶體釋放,指標的存在,一直都是很困擾的乙個問題,怎樣釋放資源,成了很大的難題,本文拋磚引玉,整理自己對記憶體的一些理解,並記錄下來,不對之處,還望不吝指正。在c 中,記憶體分成5個區,他們分別是堆 棧 自由儲存區 全域性 靜態儲存區和常量儲存區。棧,在執行函式時,函式內區域性變數的儲存單元都可...
C 釋放資源
什麼是資源?net 框架中如何訪問資源?在物件導向的環境中,每乙個型別都標識為某些程式所用的資源,要想使用這些資源,必須為相應的型別分配一定的記憶體空間。訪問乙個資源需要如下幾個步驟 1 分配記憶體空間 呼叫中間語言 il 中的newobj指令 使用new操作符時,將產生newobj指令 為某個特定...
C 資源釋放
雖然在.net程式設計過程中,絕大多數記憶體垃圾 由clr 公共語言執行時 自動 但也有很多需要我們編碼 掌握託管與非託管的基本知識,可以有效避免某些情況下導致的程式異常。託管 就是visual basic net和c 編譯器編譯出來的 編譯器把 編譯成中間語言 il 而不是能直接在你的電腦上執行的...