非託管資源的釋放

2022-09-16 06:24:11 字數 1205 閱讀 7075

與c++一樣,c#可以定義析構函式。但c#的析構函式主要用於釋放託管資源。在net中,由gc垃圾**執行緒掌握物件資源的釋放,程式設計師無法掌控析構函式的呼叫時機。為了完全掌控非託管資源的釋放,net提供乙個idisposable介面。

問題:finalize()和dispose()之間的區別?

最簡單的解釋是:finalize自動釋放資源,dispose()用於手動釋放資源。finalize很像c++的析構函式,在**中的實現也很像,但它的呼叫過程卻大不相同。例如類a中實現了finalize函式,在a的乙個物件a被建立時,它的指標被插入到乙個finalization鍊錶中,在gc執行時,它將查詢finalization鍊錶中的物件指標,如果此時a已經是垃圾物件的話,它會被移入到乙個freachable佇列中,最後gc會呼叫乙個高優先順序執行緒,此執行緒專門負責遍歷freachable佇列並呼叫佇列中所有物件的finalize方法,至此,物件a中的非託管資源才得到釋放,而a所占用的記憶體資源則必須等到下一次gc才能釋放,所以乙個實現了finaliza方法的物件必須等兩次gc才能被完全釋放。

由於finalize是由gc負責呼叫,可以說是一種自動的釋放方式。裡面牽涉到兩個問題:1是無法確定gc何時運作,有可能很長時間不釋放物件資源。2是會帶來微妙的依賴性問題,因為負責的執行緒並不保證物件的finalize呼叫的順序。可見自動釋放資源不能滿足我們的需求,因為我們不能顯式地呼叫它(它只能由gc呼叫),而且具有依賴性的問題,我們需要更準確地控制資源的釋放。

dispose方法:

dispose是提供給我們顯式呼叫的方法。

using (){}能自動呼叫dispose方法。

在電腦科學中,記憶體洩漏(memory leak)指由於疏忽或錯誤造成程式未能釋放已經不再使用的記憶體的情況。記憶體洩漏並非指內存在物理上的消失,而是應用程式分配某段記憶體後,由於設計錯誤,失去了對該段記憶體的控制,因而造成了記憶體的浪費。記憶體洩漏與許多其他問題有著相似的症狀,並且通常情況下只能由那些可以獲得程式源**的程式設計師才可以分析出來。然而,有不少人習慣於把任何不需要的記憶體使用的增加描述為記憶體洩漏,嚴格意義上來說這是不準確的。

一般我們常說的記憶體洩漏是指堆記憶體的洩漏。堆記憶體是指程式從堆中分配的,大小任意的(記憶體塊的大小可以在程式執行期決定),使用完後必須顯式釋放的記憶體。應用程式一般使用malloc,calloc,realloc等函式(c++中使用new操作符)從堆中分配到一塊記憶體,使用完後,程式必須負責相應的呼叫free或delete釋放該記憶體塊,否則,這塊記憶體就不能被再次使用,我們就說這塊記憶體洩漏了。

C 釋放非託管資源

c 中資源分為託管資源和非託管資源。託管資源由垃圾 器控制如何釋放,不需要程式設計師過多的考慮 當然也程式設計師也可以自己釋放 非託管資源需要自己編寫 來釋放。那麼編寫好的釋放非託管資源的 釋非 由誰來呼叫呢。有兩種實現方式 一 將釋非 放到建構函式析構函式中,由系統自動呼叫,系統會在資源物件不再使...

非託管資源建立與釋放

現象 主程式呼叫我的dll庫無法執行 異常資訊顯示 bug exception 引數無效。system.argumentexception stack trace 在 system.drawing.graphics.checkerrorstatus int32 status 在 system.dra...

託管資源和非託管資源

託管資源 net可以自動進行 的資源,主要是指託管堆上分配的記憶體資源。託管資源的 工作不需要人工干預的,有.net執行庫在合適時呼叫垃圾 器進行 非託管資源 是.net不知道如何 的資源,最常見的一類非託管資源是包裝作業系統資源的物件,如檔案,視窗,網路連線,資料庫連線,畫刷,圖示等。這類資源,垃...