2010-05-18 142 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中封装内存块,与非托管堆分开,但没有一般地方存在非托管资源。相反,正如所指出的,非托管资源可以是任何事情,并且可以存储在任何地方。