託管與非託管

在clr上編譯運行的代碼就是託管代碼 
非CLR編譯運行的代碼就是非託管代碼

C#託管資源和非託管資源

在C#中,資源分爲託管資源和非託管資源兩種。GC在回收無用對象資源時,可以自動回收託管資源(比如託管內存),但對於非託管資源(比如Socket、文件、數據庫連接)必須在程序中顯式釋放。

    託管資源的回收首先需要GC識別無用對象,然後回收其資源。一般無用對象是指通過當前的系統根對象和調用堆棧對象不可達的對象。對象有一個重要的特點導致無用對象判斷的複雜性:對象間的相互引用!如果沒有相互引用,就可以通過“引用計數”這種簡單高效的方式實現無用對象的判斷,並實現實時回收。正是由於相互引用的存在導致GC需要設計更爲複雜的算法,這樣帶來的最大問題在於喪失了資源回收的實時性

對於非託管資源的釋放,C#提供了兩種方式:

1.Finalizer:寫法貌似C++的析構函數,本質上卻相差甚遠。Finalizer是對象被GC回收之前調用的終結器,初衷是在這裏釋放非託管資源,但由於GC運行時機的不確定性,通常會導致非託管資源釋放不及時。另外,Finalizer可能還會有意想不到的副作用,比如:被回收的對象已經沒有被其他可用對象所引用,但Finalizer內部卻把它重新變成可用,這就破壞了GC垃圾收集過程的原子性,增大了GC開銷。

2.Dispose Pattern:C#提供using關鍵字支持Dispose Pattern進行資源釋放。這樣能通過確定的方式釋放非託管資源,而且using結構提供了異常安全性。所以,一般建議採用Dispose Pattern,並在Finalizer中輔以檢查,如果忘記顯式Dispose對象則在Finalizer中釋放資源。

可以說,GC爲程序帶來安全方便的同時也付出了不小的代價:一則喪失了託管資源回收的實時性,這在實時系統和資源受限系統中是致命的;二則沒有把C#託管資源和非託管資源的管理統一起來,造成概念割裂。C++的定位之一是底層開發能力,所以不難理解GC並沒有成爲C++的語言特性。雖然我們在C++0x和各種第三方庫都能看到GC的身影,但GC對於C++來講並不是那麼重要,至多是一個有益的補充。C++足以傲視C,並和C# GC一較高下的是它的RAII。以上介紹C#託管資源和非託管資源

,而變成一種不確定的方式。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章