【问题标题】:Who is responsible for C# memory allocation?谁负责 C# 内存分配?
【发布时间】:2015-05-07 18:30:25
【问题描述】:

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

【问题讨论】:

  • 我很确定是运行时...
  • CLR 分配和 GC 解除分配! CLR 使用该 Deallocated 内存进行下一次分配。所以循环继续,所以我会说两者都有责任...... :)
  • @JenishRabadiya 好吧,不完全是。 GC 不仅仅是堆释放的东西,它实际上是堆,所以你不能真的说它不参与分配,它实际上非常参与分配.

标签: c# .net garbage-collection clr


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    内存分配

    "一般 .NET 使用 Host 进程托管,在调试 .NET 期间 使用 VSHost.exe 创建一个进程,为程序员提供 IDE 的基本调试工具以及直接托管内存 CLR 的管理。部署应用程序后,CLR 以其可执行文件的名称创建进程并分配内存 直接通过托管堆。

    加载CLR时,一般会分配两个托管堆;一个是 用于小物体,其他用于大物体。我们一般称它为 SOH(小对象堆)和 LOH(大对象堆)。现在当任何 处理内存请求,它将请求传输到 CLR,然后 根据这些托管堆的大小分配内存。 通常,SOH 分配给内存请求的大小时 内存小于 83 KB(85,000 字节)。如果大于这个, 它从 LOH 分配内存。关于内存.NET越来越多的请求 以较小的块提交内存。”

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

    “解除分配”由 GC 管理。

    "对象与相关进程之间的关系 该对象通过图表进行维护。当垃圾收集 触发它认为图中的每个对象都是垃圾并遍历 递归到与关联的图的所有关联路径 寻找可达对象的对象。每次垃圾 收集器到达一个对象,它将对象标记为可达。现在 完成这个任务后,垃圾收集器知道哪些对象是 可达,哪些不可达。无法访问的对象被视为 垃圾到垃圾收集器。”

    【讨论】:

      【解决方案3】:

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

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

      虽然 .NET 有时必须在某些对象(例如,其类型覆盖 Finalize 的对象)被发现已被放弃时采取肯定行动,但总的来说,我认为最好将“GC”视为不是“收集”垃圾的子系统,而是作为垃圾收集内存池的管理器,需要始终了解所有不是垃圾的东西。虽然经理的职责包括执行 GC 周期,但它们远不止于此,而且我认为将 GC 周期与其他职责分开是没有用的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-05
        • 2012-10-04
        • 1970-01-01
        相关资源
        最近更新 更多