2010-08-31 178 views

回答

54

術語「非託管資源」通常用於描述不直接處於垃圾收集器的控制下的東西。例如,如果打開與數據庫服務器的連接,則會使用服務器上的資源(用於維護連接)以及客戶端計算機上的其他非.NET資源(如果提供程序未完全用託管代碼寫入)。

這是爲什麼,像一個數據庫連接,建議你寫的正是如此代碼:

using (var connection = new SqlConnection("connection_string_here")) 
{ 
    // Code to use connection here 
} 

因爲這確保.Dispose()被稱爲連接對象上,確保任何非託管資源的及時清理。

+8

我會稍微澄清一點:「非託管資源」是垃圾收集器在丟棄之後不知道如何清理的內容。例如,短暫對象從長壽命對象訂閱事件,即使兩個對象都處於垃圾收集器的控制之下,也是非託管資源,因爲GC無法知道訂閱如果訂閱者被放棄但發行者不在,應該報廢。如果在發佈者的生命週期中可以創建和放棄無限數量的訂閱者,那會導致內存泄漏。 – supercat 2011-08-12 19:47:43

+8

增加一點說明:SqlConnection(或FileStream等)是管理資源,它們在內部使用GC不知道的非託管資源。 – jimvfr 2013-01-17 02:21:23

+1

jimvfr是對的,SqlConnection是一個管理資源的例子。非託管資源的一個例子是,當我們需要使用Marshal.AllocHGlobal()方法從非託管內存分配內存時,在這種情況下,最好的做法是使用析構函數(〜ctor)並調用Marshal.FreeHGlobal()釋放這個內存。 – 2014-07-30 17:13:31

23

管理資源是那些純粹的.NET代碼,由運行時管理並受其直接控制。

非託管資源是那些不是。文件句柄,固定內存,COM對象,數據庫連接等。

6

之間的基本差異託管和非託管資源就是 垃圾收集知道的所有管理資源,在某個時間點 的GC會來清理所有的內存和相關 與被管理對象資源。 GC不知道非託管資源,例如 作爲文件,流和句柄,所以如果您沒有明確地清除它們在 您的代碼,那麼您將最終與內存泄漏和鎖定的資源。

詳情 - http://bytes.com/topic/c-sharp/answers/276059-what-unmanaged-resources

+1

「IDisposable接口背後的想法是讓您以確定性的方式清理資源並清理非託管資源。」真棒! – zionpi 2013-11-14 06:53:02

0

管理的資源是可以被垃圾收集器被釋放和非託管資源能爲需要爲此析構函數不會被垃圾收集器釋放的資源。

4

在問答&一個What are unmanaged resources?布魯斯·伍德貼內容:

我認爲術語 「管理」 和 「非託管」 這種方式:

「管理「引用.NET沙箱中的任何內容。這包括所有.NET Framework類的 。

「非託管」指的是.NET沙箱之外的荒野。此 包括通過調用Win32 API 函數返回給您的任何內容。

如果從未調用Win32 API函數和從未取回任何的Win32 「處理」的對象,那麼你就不會持有任何非託管資源。 通過.NET Framework類方法打開的文件和流爲 所有託管包裝。

評論:您可能沒有持有非託管資源直接。但是,您可能會通過託管的「包裝類」(例如System.IO.FileStream)間接持有非託管資源。這樣的包裝類通常實現IDisposable(直接或通過繼承)。

...許多管理(.NET Framework)的對象 持有非託管資源在他們裏面,你可能馬上要他們的 Dispose()方法就可以了,或者至少提供來電者 的有機會這樣做。這就是寫自己的Dispose() 方法來在本質上,實施了IDisposable()做了兩米 你的東西:

  1. 讓您擺脫任何資源可以直接從 操作系統後面抓住.NET的背後(非託管資源)。

  2. 讓您和您調用者釋放沉重的.NET對象/ .NET 對象在他們的骯髒的小 手中拿着寶貴的資源,你/你的來電者想要發佈現在

評論:通過實施IDisposable從而提供一個Dispose()方法,你讓你的類在確定性時尚釋放被持有的非託管資源的用戶通過一個實例類。


鏈路最初在Sachin Shanbhag's answer共享。引用日期爲2005-11-17的材料。請注意,我輕輕地複製了所引用的內容。