深入挖掘CLR內存管理機制原理
C++的許多程序員都中,最頭疼的是對內存的分配和管理。用.net就不一樣了。.net引用了垃圾回收(GC)功能,它替代了程序員對于清除無用對象的工作。雖然在大多數情況下,內存的回收我們不用再去理會,但如果能夠在程序中適時地添加一些內存管理的工作,可以使程序更加的優化,來看看CLR內存管理機制 。
由于CLR(公共語言運行時)可以知道在系統中的所有對象引用,而CLR內存管理機制在運行時,GC可以獲取對象是否被引用的信息。如果一個對象不再被引用,則通過GC進行自動回收。
不過GC回收的條件是,當特定資源不夠用時才執行。如果我們希望自己控制,也可以顯示地指示GC工作。方法是:
- System.GC.Collect();
GC在進行回收時,先會識別對象是否被引用,并標記出對象的特征。只有不被引用的對象才被回收。為避免堆碎片,GC在回收了對象后,會重新分配內存,并對未被回收的對象進行重定位。這必然導致GC在回收時會導致系統運行性能的降低。
適時的進行人工干預內存分配,是比較好的選擇。我們知道在C++中,對于創建的類中,有相對應的析構函數進行內存的刪除。在C#中,也可以采用同樣的方式。當實例化一個類對象后,刪除它,則自動調用其析構函數。CLR提供了對象終結(object finalization)的機制,引入了Finalize方法。不過在C#中,不能直接實現Finalize方法,而是在析構函數中調用基類的Finalize()方法。
GC的回收機制是異步操作,我們可以使用CLR提供的Dispose()方法實現對每一個對象的刪除操作。Dispose()方法由IDiposable接口提供。因此對于將要實例化的類對象,實現Dispose操作,必須使類實現該接口,并提供Dispose()方法。
- public class Garbage:IDisposable//實現該接口
- {
- public void Dispose()//提供Dispose()方法;
- {
- GC.SuppressFinalize(this);//回收該對象;
- }
- ~Garbage()//析構函數;
- {
- Dispose();
- }
- }
不過更好的方案是使用using語句。將對象的實例放到using中,一旦using結束,系統會自動清楚該對象。
- using (Garbage g = new Garbage())
- {
- //執行操作;
- }
不過要注意的是在using語句中實例的對象,其類也必須要實現IDisposable接口和Dispose()方法。另外,由于IComponent擴展了IDisposable,因此IComponent類型始終是IDisposable類型。所以我們開發的組件類型可以用在using中,或者使用Dispose()方法。所以,系統提供的組件如DataSet,DataTable等的實例也可以實現這種方式來清除對象。以上就是CLR內存管理學會了嗎?
【編輯推薦】