C#中托管與非托管


  在.net 編程環境中,系統的資源分為托管資源和非托管資源。

  對於托管的資源的回收工作,是不需要人工干預回收的,而且你也無法干預他們的回收,所能夠做的

只是了解.net CLR如何做這些操作。也就是說對於您的應用程序創建的大多數對象,可以依靠 .NET

Framework 的垃圾回收器隱式地執行所有必要的內存管理任務。

  對於非托管資源,您在應用程序中使用完這些非托管資源之后,必須顯示的釋放他們,例如

System.IO.StreamReader的一個文件對象,必須顯示的調用對象的Close()方法關閉它,否則會占用系統

的內存和資源,而且可能會出現意想不到的錯誤。

  我想說到這里,一定要清楚什么是托管資源,什么是非托管資源了?

  最常見的一類非托管資源就是包裝操作系統資源的對象,例如文件,窗口或網絡連接,對於這類資源

雖然垃圾回收器可以跟蹤封裝非托管資源的對象的生存期,但它不了解具體如何清理這些資源。還好.net

Framework提供了Finalize()方法,它允許在垃圾回收器回收該類資源時,適當的清理非托管資源。如果

在MSDN Library 中搜索Finalize將會發現很多類似的主題,這里列舉幾種常見的非托管資源:

ApplicationContext,Brush,Component,ComponentDesigner,Container,Context,Cursor,FileStream,Fon

t,Icon,Image,Matrix,Object,OdbcDataReader,OleDBDataReader,Pen,Regex,Socket,StreamWriter,Time

r,Tooltip 等等資源。可能在使用的時候很多都沒有注意到!

關於托管資源,就不用說了撒,像簡單的int,string,float,DateTime等等,.net中超過80%的資源都是托

管資源。

非托管資源如何釋放,.NET Framework 提供 Object.Finalize 方法,它允許對象在垃圾回收器回收該對象使用的內存時適當清理其非托管資源。默認情況下,Finalize 方法不執行任何操作。如果您要讓垃圾回收器在回收對象的內存之前對對象執行清理操作,您必須在類中重寫 Finalize 方法。然而大家都可以發現在實際的編程中根本無法override方法Finalize(),在C#中,可以通過析構函數自動生成 Finalize 方法和對基類的 Finalize 方法的調用。

例如:
~MyClass()
{
  // Perform some cleanup operations here.
}
  該代碼隱式翻譯為下面的代碼。
protected override void Finalize()
{
  try
  {
    // Perform some cleanup operations here.
  }
  finally
  {
    base.Finalize();
  }
}

但是,在編程中,並不建議進行override方法Finalize(),因為,實現 Finalize 方法或析構函數對性能

可能會有負面影響。一個簡單的理由如下:用 Finalize 方法回收對象使用的內存需要至少兩次垃圾回收

,當垃圾回收器回收時,它只回收沒有終結器(Finalize方法)的不可訪問的內存,這時他不能回收具有終

結器(Finalize方法)的不可以訪問的內存。它改為將這些對象的項從終止隊列中移除並將他們放置在標記

為“准備終止”的對象列表中,該列表中的項指向托管堆中准備被調用其終止代碼的對象,下次垃圾回收

器進行回收時,就回收並釋放了這些內存。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM