來源:http://blog.csdn.net/lanbaibai
近期看了看有關.net的記憶體回收方面的知識,感覺有必要將這方面的資料總結一下,和廣大網友分享一下
.net的記憶體回收,借鑒了java的記憶體回收機制。在以前的windows環境下,我們執行個體化一個對象後,我們經常會忘記
釋放掉已經無用的記憶體,或者試圖使用已經釋放掉的記憶體,造成程式的崩潰。但是隨著.net中的記憶體回收機制出現,
這種情況得到了大大的改善。
在.net中兩種變數類型,一種是實值型別,一種是參考型別,實值型別所佔的記憶體,存放在當前線程的棧上,記憶體回收
不負責回收這方面的記憶體,當前方法運行完畢後,記憶體會自動釋放。參考型別所佔的記憶體存放在託管堆上,
.net的記憶體回收就是負責回收這方面的記憶體資源。
在.net中提供三種模式來回收記憶體資源:dispose模式,finalize方法,close方法。
dispose提供了一種顯示釋放記憶體資源的方法。dispose調用方法是:要釋放的資來源物件.dispose
finalize方法是.net的內部的一個釋放記憶體資源的方法。這個方法不對外公開,由記憶體回收行程自己調用。
close和dispose其實一樣,只不過有的對象沒有提供dispose的方法,只提供了close方法,而close其實在
那個對象的類中,依然是調用了一個私人的dispose方法,而finalize其實也是調用一個不對外公開的dispose方法
那麼既然.net在記憶體回收中了finalize方法,那麼為什麼還要提供dispose方法和close方法哪?這是因為finalize方法會釋放
掉託管堆記憶體和非託管堆記憶體。而dispose只會釋放掉非託管的記憶體資源,對於託管的記憶體資源它不會釋放,只能由記憶體回收拉釋放。
當我們開啟一個資料庫連接的時候(這是一個非託管記憶體資源),如果我們不手工釋放這一部分資源,
等下一次記憶體回收調用finalize方法回收資源,那麼可能會是很長的時間之後,所以要使用dispose這個方法。所以當我們使用
sqlconnection這個對象串連資料庫後,調用sqlconnnection.dispose方法後,可以從資料庫中斷連線,但是sqlconnection這個
對象沒有消亡,這個對象可以繼續使用,直到下一次記憶體回收調用finalize方法回收資源。
我們再說一下close這個方法,我們上面提到過了,它起到的作用和dispose一樣。只不過有的.net有的對象沒有提供dispose方法,
而是用close代替,因為用close代替,比dispose顯得更直觀。
下面用一個例子說明finalize和dispose,close的區別
大家看下面的代碼
dim a as string="1234"
dim fs as filestream("temp.txt",fileMode,create)
fs.write(a) ''''向檔案寫入內容
fs.dispose() '''顯示關閉檔案
fs.write(a) ''''拋出錯誤
因為當我們調用了dispose方法,我們只是關閉了temp.txt檔案,fs對象是一個託管對象,他的資源沒有被釋放,依然可以使用,但是
temp.txt檔案已經關閉,向一個已經關閉的檔案寫入內容,當然會出錯。
大家再看下面的代碼
dim a as string="1234"
dim fs as filestream("temp.txt",fileMode,create)
dim bw as new binarywrite(fs)
bw.write(a) ''''向檔案寫入內容
bw.dispose() '''顯示關閉檔案,我們調用binarywriter.close會同時關閉filestream對象,所以不用調用fs.close方法
binarywriter接受一個filestream為對象,當我們向binarywriter對象寫入資料時,其實儲存在記憶體緩衝中,當記憶體緩衝寫滿時,binarywriter
才會將資料寫入檔案中。
我們調用bw.dispose會導致binarywriter對象將資料填入到filestream中,同時關閉filestream對象,當filestream對象關閉,它會將緩衝區的
內容填入到磁碟檔案中。而如果我們沒有顯示的調用dispose或者close方法,記憶體回收行程會先中止filestream對象,關閉檔案。這樣緩衝區的內容會
丟失,寫入失敗。