谁负责 C# 内存分配?

Who is responsible for C# memory allocation?

.NET 框架的哪一部分负责分配内存。是GC吗?

它是 CLR 但与 GC 密切合作。而 GC 是 CLR 的一部分,所以并不是那么明确的划分。

分配发生在堆的空闲部分的开始,这是一个非常简单和快速的操作。大型对象堆 (LOH) 上的分配稍微复杂一些。

拜访http://www.codeproject.com/Articles/38069/Memory-Management-in-NET

内存分配

"Generally .NET is hosted using Host process, during debugging .NET creates a process using VSHost.exe which gives the programmer the basic debugging facilities of the IDE and also direct managed memory management of the CLR. After deploying your application, the CLR creates the process in the name of its executable and allocates memory directly through Managed Heaps.

When CLR is loaded, generally two managed heaps are allocated; one is for small objects and other for Large Objects. We generally call it as SOH (Small Object Heap) and LOH (Large Object Heap). Now when any process requests for memory, it transfers the request to CLR, it then assigns memory from these Managed Heaps based on their size. Generally, SOH is assigned for the memory request when size of the memory is less than 83 KBs( 85,000 bytes). If it is greater than this, it allocates memory from LOH. On more and more requests of memory .NET commits memory in smaller chunks."

进一步阅读本段后,它是 CLR 在 Windows(32 位或 64 位)的帮助下 "allocates" 内存。

"De-allocation" 由 GC 管理。

"The relationships between the Object and the process associated with that object are maintained through a Graph. When garbage collection is triggered it deems every object in the graph as garbage and traverses recursively to all the associated paths of the graph associated with the object looking for reachable objects. Every time the Garbage collector reaches an object, it marks the object as reachable. Now after finishing this task, garbage collector knows which objects are reachable and which aren’t. The unreachable objects are treated as Garbage to the garbage collector."

尽管名称如此,但许多现代 "garbage collectors" 实际上并不将收集垃圾作为其主要操作。相反,他们经常识别内存区域中不是垃圾的所有内容,并将其移动到已知不包含任何有价值内容的地方。除非该区域包含一个 "pinned" 且无法移动的对象(在这种情况下事情会更复杂),系统将知道从中移动内容的内存区域不包含任何有价值的东西。

在许多这样的收集器中,一旦对对象的最后引用消失,在被新数据盲目覆盖之前,与该对象关联的内存字节将不再被检查。如果 GC 期望下一次使用旧内存区域将用于保存新对象,它可能会一次性清零所有字节,而不是零碎地这样做以满足分配,但如果 GC 期望它将用作从其他地方复制的对象的目的地,它可能不会打扰。只要任何引用存在,对象就一定会保留在内存中,但是一旦对象的最后一个引用不复存在,就无法知道分配给该对象的每个内存字节是否实际上已被覆盖。

虽然 .NET 有时必须在某些对象(例如类型覆盖 Finalize 的对象)被发现已被放弃时采取平权行动,但通常我认为最好考虑 "GC" 不是 "collects" 垃圾的子系统,而是垃圾收集内存池的 管理器 ,它需要 始终 随时了解所有不是垃圾的信息。虽然经理的职责包括 GC 循环的性能,但它们远不止于此,而且我认为将 GC 循环与其他职责分开是没有用的。