IDispose和Finalize的區別和聯絡

2022-01-13 06:01:16 字數 1526 閱讀 3735

產生了兩個問題(**中紅色標註區域):

問題1:為什麼在析構函式中呼叫的是「dispose(false);」,也就是為什麼gc垃圾**機制在**對

象的時候只**或者釋放非託管資源,而不**託管資源?

問題2:在「dispose()」中「gc.suppressfinalize(this);」是什麼意思?

上網搜了寫資料,終於了解了這種設計的用意和優點:

參考資料:

解答問題1:

在.net的物件中實際上有兩個用於釋放資源的函式:dispose和finalize。finalize的目的是用於釋放非託管的資源,而dispose是用於釋放所有資源,包括託管的和非託管的。

在這個模式中,通過乙個變數「disposing」來區分是客戶呼叫(true)還是gc呼叫(false)。

這是因為,dispose()函式是被其它**顯式呼叫並要求釋放資源的,而finalize是被gc呼叫的。

在gc呼叫的時候myresource所引用的其它託管物件(component)可能還不需要被銷毀,並且即使

要銷毀,也會由gc來呼叫。因此在finalize中只需要釋放非託管資源即可。

解答問題2:

由於在dispose()中已經釋放了託管和非託管的資源,因此在物件被gc**時再次呼叫finalize是

沒有必要的,所以在dispose()中呼叫gc.suppressfinalize(this)避免重複呼叫finalize。

因此,上面的模式保證了:

1、 finalize只釋放非託管資源;

2、 dispose釋放託管和非託管資源;

3、 重複呼叫finalize和dispose是沒有問題的;

4、 finalize和dispose共享相同的資源釋放策略,因此他們之間也是沒有衝突的。

在c#中,這個模式需要顯式地實現,其中c#的~myresource()函式代表了finalize()。

優點:

1、如果客戶沒有呼叫dispose(),未能及時釋放託管和非託管資源,那麼在垃圾**時,還有機會執

行finalize(),釋放非託管資源,但是造成了非託管資源的未及時釋放的空閒浪費。

2、如果客戶呼叫了dispose(),就能及時釋放了託管和非託管資源,那麼該物件被垃圾**時,不回

執行finalize(),提高了非託管資源的使用效率並提公升了系統效能。

此外還有close()方法,此方法一般和open()方法配合來使用,對於資料庫連線,一般可以逆向操作,比如開啟->關閉,關閉->開啟,而對於檔案操作,一般是關閉檔案,相當於dispose(),而且有的使用者更願意使用close()來釋放資源,所以出現了一下這種相當於介面卡模式的**:

publicvoidclose()

最後還要再說一點,據msdn上說c#不允許類實現finalize()方法,所以用析構函式來代替。

C 實現IDispose介面

net的gc機制有兩個問題 首先gc並不能釋放所有資源,它更不能釋放非託管資源。其次,gc也不是實時的,所有gc存在不確定性。為了解決這個問題donet提供了析構函式 public class testclass system.idisposable protected的dispose方法,保證不會...

C 實現IDispose介面

net的gc機制有兩個問題 首先gc並不能釋放所有資源,它更不能釋放非託管資源。其次,gc也不是實時的,所有gc存在不確定性。為了解決這個問題donet提供了析構函式 public class testclass system.idisposable protected的dispose方法,保證不會...

如何實現真正的IDispose?

最近在專案開發的過程中,我們的乙個資料同步程式碰到了資源無法釋放的問題。我使用的定位方法是效能計數器 perfmon.msc 顯然這只是乙個很粗礦的判斷。後通過code review我們的 中定義了乙個同步的中間類,該類中會快取大量的中間資料集。而程式中麼有及時的 這些臨時物件,最終我建議該類實現一...