不要多次釋放物件 的小隨筆

2022-02-06 12:23:51 字數 2035 閱讀 6654

【題外話】

之前大部分時間都在用visual studio 2008做開發,雖然也點開過**分析,但是一看一大串內容,尤其是一大串針對命名的建議,就果斷關閉了。這次實習使用的visual studio 2012,發現**分析預設去掉了很多內容,顯示的也都是比較重要並需要改進的地方,所以也都認真研究了一下。

【文章索引】

問題和解決方法

為什麼這樣去做

相關鏈結

【一、問題和解決方法】

應該有人會寫如下的**吧,為了釋放資源,我們把開啟的東西都關閉掉,貌似沒有什麼問題。

1 filestream fs = null

;2 streamreader sr = null;3

4try511

finally

1217

18if (fs != null)19

22 }

當然,喜歡用using的同學也可能會寫如下的**:

1

using (filestream fs = new filestream(@"

f:\test.txt

", filemode.open, fileaccess.read))

27 }

但是這兩種**如果使用**分析會出現什麼情況呢,如下圖。

比較有意思的是,這裡提示的是「不應對乙個物件多次呼叫 dispose」,為什麼會是「乙個物件」呢?

通過翻閱msdn中的ca2202(鏈結在文後),我們可以查到原因是這樣的,「某個方法實現所包含的**路徑可能導致對同一物件多次呼叫 idisposable.dispose 或與 dispose 等效的方法(例如,用於某些型別的 close() 方法)」,msdn中直接給出了解決方法就是不要關閉streamreader,而是直接關閉filestream。

【二、為什麼這樣去做】

msdn給出的方法為什麼要這樣做呢?出於好奇心,首先拿上述的**單步除錯一下:

在執行完streamreader的close之後,streamreader的basestream指向了null,同時fs也變為了不能讀取,但fs不是null。

然後我們用reflector找到streamreader的實現(在mscorlib.dll檔案中)如下:

1

public

override

void

close()25

6protected

override

void dispose(bool

disposing)714

}15finally

1628

}29 }

streamreader在執行close時竟然執行了this.stream(basestream)的close,然後將basestream再指向null,這就解決了之前為什麼提示不要多次釋放乙個物件,其實是streamreader的close已經釋放了一次而已。當然,不僅僅是streamreader是這樣子,streamwriter、binaryreader等等也都是這樣子的。

可是,為什麼msdn的例子給的是關閉流而不是關閉讀取器呢?

翻閱了網上也沒有找到權威的資料,所以個人總結了幾點如下僅供參考:

1、關閉streamreader等其實已經關閉了其basestream,但容易使開發者誤以為basestream沒有關閉而繼續使用導致丟擲異常,所以關閉最基礎的流會更好些。

2、streamreader等本身並沒有使用非託管的內容,所以也無需主動執行close,讓gc去做就好了。

【三、相關鏈結】

1、ca2202:不要多次釋放物件:

Objective C ARC自動釋放物件記憶體

arc是cocoa系統幫你完成物件記憶體釋放的引用計數機制 h檔案 1 01 arc3 4 created by ma c on 15 8 13.5 6 78 import910 inte ce person nsobject 11 property nonatomic,strong nsstrin...

Linux Slub分配器 五 釋放物件

釋放物件和分配物件是一組對稱的操作,同樣分為兩個路徑 1.如果待釋放的物件所屬的slab位於本地cpu快取中,也就是slab處於凍結狀態,則可直接釋放 2.反之,待釋放的物件所屬的slab位於slab鍊錶中,也就是slab處於解凍狀態,則要通過慢速路徑進行釋放。函式kmem cache free 用...

vector中存放物件和指標的區別

這裡先說出結論 vector中push back物件時,會呼叫物件的拷貝建構函式。而且在vector空間不足時,繼續push back,vector會將之前的所有物件都拷貝構造到一塊更大的空間裡。也就是說物件如果較大,那麼最好用vector儲存指標以減少呼叫拷貝構造 造成的消耗,如果vector存指...