【題外話】
之前大部分時間都在用visual studio 2008做開發,雖然也點開過**分析,但是一看一大串內容,尤其是一大串針對命名的建議,就果斷關閉了。這次實習使用的visual studio 2012,發現**分析預設去掉了很多內容,顯示的也都是比較重要並需要改進的地方,所以也都認真研究了一下。
【文章索引】
問題和解決方法
為什麼這樣去做
相關鏈結
【一、問題和解決方法】
應該有人會寫如下的**吧,為了釋放資源,我們把開啟的東西都關閉掉,貌似沒有什麼問題。
1 filestream fs = null當然,喜歡用using的同學也可能會寫如下的**:;2 streamreader sr = null;3
4try511
finally
1217
18if (fs != null)19
22 }
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檔案中)如下:
1streamreader在執行close時竟然執行了this.stream(basestream)的close,然後將basestream再指向null,這就解決了之前為什麼提示不要多次釋放乙個物件,其實是streamreader的close已經釋放了一次而已。當然,不僅僅是streamreader是這樣子,streamwriter、binaryreader等等也都是這樣子的。public
override
void
close()25
6protected
override
void dispose(bool
disposing)714
}15finally
1628
}29 }
可是,為什麼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存指...