簡說GC垃圾回收

 

前記:

之所以研究GC是因爲之前寫的一個實時截屏軟件(每隔一段時間截一次屏),發現它的內存消耗驚人,往往開始運行時3M左右,但是幾十分鐘後就飆到600+M。於是開始研究GC,優化後現在一直保持在4~5M。

 

一、什麼是GC

關於GC,是個比較大的話題,很多平臺都有GC機制,除了C#還有java,甚至Javascript等。我們的話題主要面對C#。

C#的GC是一種.Net特性,它不斷回收不再使用的託管資源對象,爲將要使用內存的對象開闢空間。回收的過程是由.Net自動運行管理的,但是程序員也可以通過代碼干預。

 

二、託管資源與非託管資源

 
託管資源指託管於.Net機制的資源對像,如int,double,float等等。.Net中80%都是託管資源,他們會被GC及時清理。
 
非託管資源指非.Net機制託管對象,如圖像對象,數據庫連接對象等等。
非託管資源大體有:
ApplicationContext,Brush,Component,ComponentDesigner,Container,Context,Cursor,
FileStream,Font,Icon,Image,Matrix,Object,OdbcDataReader,OleDBDataReader,Pen,
Regex,Socket,StreamWriter,Timer,Tooltip 等
 
 

三、清理非託管資源

GC會自動回收託管資源對象,但是非託管資源對象GC並不知道如何處理,這就需要程序員處理非託管資源的清空方式。
實現方式有兩種:
實現IDisposable接口的DIspose方法;
實現析構方法;
兩者的區別在於,當一個類實現IDisposable接口後,在使用該類時通過主動調用Dispose方法,或者使用using語句使用該類(using語句執行完畢會執行Dispose方法,即便出現中間異常),皆可及時清理非託管資源。
實現的析構方法卻屬於“被動”,只有GC執行清理時,若發現該類有析構方法,就會主動調用。
兩者並不衝突,但是實際上一個類只需要一種就夠了。而且建議使用Dispose方式。
 

四、GC底層原理

 
在GC中有一個計數器,他會在一個對象創建時,將其納入計數器,並計數爲0。當某處使用該對象時,計數+1,當某處該對象使用完畢,或置爲null,則計數-1。(計數數值永遠保持大於等於0.)
 
當GC開啓回收並發現一個對象的計數爲0時,會將其清理掉,釋放對應內存。
 
託管資源由於是由.Net機制完全控制監管的,他的計數會嚴格且有效,所以能夠及時清理。但是非託管資源由於.Net不清楚該對象會在什麼時候不再使用,其計數方式就需要程序員手動管理。當手動處理計數之後(通過Dispose或析構),GC就會知道誰應該被清理,非託管資源也就順利被GC回收了。
 
 
 
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章