我不是一个科学家。托管资源在堆上分配。但我想知道在哪里分配了非托管资源。如果还在堆上分配了非托管资源,它是否与托管资源使用的堆相同或不同?
提前致谢。
戒
答案 0 :(得分:10)
从操作系统视图来讲,堆本质上是相同的:分配给OS进程的内存空间。
不同之处在于,当CLR(.net VM)加载到Windows进程中时,它会占用此堆的一部分并将其转换为托管堆。这个内存空间成为垃圾收集器分配和了解所有托管资源的地方。
例如,如果分配了大量非托管内存并且托管堆空间不足,则可能会遇到Out of Memory错误。或者相反。
杰弗里里希特是能更好地解释这些东西的人。我强烈建议阅读他的解释:您可以使用System.InteropServices命名空间(特别是Marshal类)的服务来在堆的非托管部分和托管之间复制数据。
答案 1 :(得分:1)
要使用非托管堆操作,请使用MSDN中描述的Marshal类
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal(v=vs.71).aspx
非托管堆不受GC控制,因此内存使用的所有责任都在于您。基本上释放为非托管资源分配的内存使用IDisposable接口并自行释放所有分配的资源。 SQL连接和不同IO操作等所有非托管资源都在使用这种方法。
答案 2 :(得分:0)
在记忆中。就像任何非托管进程一样。托管堆显然与托管堆不同。
答案 3 :(得分:0)
CLR保留了自己的堆。最初,创建了两个:一个简称为managed heap(或小对象堆),另一个是large object heap(另请参阅here)。这些托管堆与CRT分配的本地堆在物理上是分开的,以便与new
和malloc
一起使用。
您可以使用VMMap检查进程分配的不同堆。
答案 4 :(得分:0)
借用比较线性和非线性过滤器的杂志文章,管理资源和非管理资源的比较就像袋鼠生物学和非袋鼠生物学之间的比较。
在.net中,托管资源是托管堆上的类对象。总是。值类型可以保存对托管资源的引用,但值类型实例本身不能“成为”托管资源。
相比之下,非托管资源可以是几乎任何东西,并且几乎可以存储在任何地方。它不需要与拥有它的程序在同一台计算机上,甚至不需要在同一个星球上(我不知道任何已发送到火星的探测器都会暴露任何类型的通信套接字接口,它会表现为一个非托管资源,但人们当然可以设计它们。)
如果某个外部实体代表该对象执行某些操作而对其他实体造成损害,则该对象持有非托管资源,并且将继续执行该操作,直到它被告知停止(或者可能,直到它超时)。有许多种非托管资源,它们可以在任何地方生活。其中一些(例如锁和事件订阅)可能完全存在于.net的托管世界中。其中一些(例如服务器连接)可能存在于任何给定时刻“拥有”它们的计算机之外。某些类型的非托管资源可以封装来自OS的内存块,与非托管堆分开,但是没有一般地方非托管资源被“存储”。相反,如上所述,非托管资源可以是几乎任何东西,并且几乎可以存储在任何地方。