2010-05-18 87 views
5

我不是科學家。託管資源分配在堆上。但我想知道未分配的資源在哪裏。如果非託管資源也分配在堆上,它是與託管資源使用的堆相同還是不同的堆?非託管資源分配在哪裏

在此先感謝。

Harsha

回答

9

從操作系統視圖來看,基本上堆是相同的:分配給OS進程的內存空間。

不同之處在於,當CLR(.net VM)在Windows進程中加載​​時,它會佔用這塊堆的一部分,並將其變爲託管堆。該內存空間成爲分配所有託管資源併爲垃圾收集器所知的地方。

例如,如果您分配一大塊非託管內存併爲託管堆空間不足,則可能會遇到內存不足錯誤。或者相反。

傑弗裏裏希特是更好地解釋這個東西的傢伙。我強烈建議你閱讀他的解釋:

可以使用System.InteropServices命名空間的業務,Marshal類具體而言,到的非託管部分之間複製數據堆和管理。

+0

這是一篇非常好的文章。爲了完整性,我還添加了它的第二部分。 – Oliver 2010-05-18 07:44:56

+0

@奧利弗:優秀!感謝編輯這個問題,而不僅僅是發表評論。 – 2010-05-18 08:15:44

+0

是的,當你獲得足夠的代表時,這是很好的功能之一(就像你已經做到的那樣)。 ;) – Oliver 2010-05-18 08:23:46

0

在內存中。就像任何非託管流程一樣。託管堆明顯不同於託管堆。

+0

實際上,非託管資源可能在任何地方 - 不一定在封裝資源的對象所在的機器上。機器外資源的一個常見示例是遠程服務器上的文件,或者與資源非常有限的設備的TCP連接(例如,許多嵌入式設備一次只支持一個TCP連接)。如果例行程序要獲取這樣的文件或TCP連接並且不立即釋放它,則可能會使其他機器上的用戶至少暫時無法訪問此類資源。 – supercat 2012-11-13 00:17:50

+0

否請參閱「遠程服務器上的文件」仍在本地分配用於管理。要保持打開狀態,你需要一個文件共享,這個文件共享偶爾不會出現,它綁定到本地服務器的文件管理堆棧上的文件打開操作。 TCP連接也以某種方式使用本地套接字。 – TomTom 2012-11-13 06:29:55

+0

儘管大多數操作系統將管理TCP套接字和遠程文件句柄之類的東西,並在應用程序退出時將其清理乾淨,但「稀缺」*是遠程計算機上的資源。本地機器的操作系統保留對遠程文件的引用,並且可以在應用程序退出時清理它並不意味着其他機器上的用戶不知道也不關心與打開的機器有關的任何事情該文件將無法訪問遠程計算機上的文件,直到發生這種情況。 – supercat 2012-11-13 20:43:22

0

該CLR維護自己的堆。最初,創建了兩個:一個簡單地稱爲managed heap(或小對象堆),另一個是large object heap(另請參閱here)。這些託管堆在物理上與CRT分配的本地堆分開,以便與newmalloc一起使用。您可以使用VMMap來檢查進程分配的不同堆。

0

借用一篇比較線性和非線性過濾器的雜誌文章,比較管理資源和非託管資源,就像比較袋鼠生物學和非袋鼠生物學。

在.net中,託管資源是託管堆上的類對象。總是。值類型有可能持有對託管資源的引用,但值類型實例本身不能「成爲」託管資源。

相比之下,非託管資源幾乎可以滿足任何需求,並且可以存儲在任何地方。它不需要與擁有它的程序在同一臺計算機上,甚至同一顆行星上(我不知道發送給Mars的任何探測器都暴露出任何類型的通信套接字接口,一個非託管資源,但當然可以設計他們這樣做)。

一個對象擁有一個非託管資源,如果某個外部實體正在代表該對象做某件事而損害他人,並會繼續做這件事,直到它被告知停止(或者可能直到它超時) 。有許多種非託管資源,他們可以在任何地方生活。其中一些(例如鎖和事件訂閱)可能完全在.net的託管世界中生存。它們中的一些(例如服務器連接)可能存在於計算機之外,在任何給定時刻「擁有」它們。某些類型的非託管資源可能會從OS中封裝內存塊,與非託管堆分開,但沒有一般地方存在非託管資源。相反,正如所指出的,非託管資源可以是任何事情,並且可以存儲在任何地方。