【问题标题】:Managed heap in CLRCLR 中的托管堆
【发布时间】:2012-10-19 21:52:39
【问题描述】:

我在 .NET 中阅读了有关 CLR 的信息:

当 CLR 加载时,堆在 SOH 和 LOH 中被分区。

  1. 当应用程序启动时,CLR 根据其大小将堆分配给应用程序。

  2. LOH 堆具有 Gen0、Gen1 和 Gen2 区域。

这里A类的所有对象都分配在Gen0上,

问题

  1. CLR 如何知道应用程序在堆中占用的大小?
  2. 假设 CLR 为 Gen0 区域分配了 4K 堆内存。鉴于下面的代码,这个单线程是否可以在 Gen0 上使用完整的 4K 内存?

    collect = new List();
    while(true)
    {
        collect.Add(new A());
        new A();
        new A();
    }
    
    class A
    {
        int a = 0, b = 0;
    }
    

【问题讨论】:

  • 1.我相信这是通过计算所有声明字段的大小来确定的,考虑到它的类型
  • 这是在应用程序启动时在堆上分配所需内存的方式。第二个问题呢?
  • 我认为 CLR 会从中查找程序集的元数据,它可以计算所需的堆。我正确吗?
  • LOH 不是世代相传的。它使用一个空闲列表。

标签: c# memory-management .net-4.0 clr


【解决方案1】:
  1. 我相信这是通过计算所有声明字段的大小来确定的,并考虑其类型。有关更多详细信息,请参阅 MSDN "Allocating Memory"
  2. 关于 MSDN 论文 "Automatic Memory Management" 所有新对象(如以下 cmets 中所述的 Brian Rasmussen - 世代仅适用于 SOH,在 LOH 中创建的大型对象不是世代修复)最初在 Gen0 中创建,并且只有那些幸存下来的对象而应用程序的生命将被移动到Gen1。但要提到的是,如果Gen0 已满 - GC 执行垃圾收集以清理 Gen0 并且如果它仍然已满 - 所有新对象都将在 Gen1 中创建。

【讨论】:

  • 谢谢,我阅读了链接。它很清楚,但有一个问题。在 while 循环中,我们在堆上分配对象,因此 CLR 现在如何提前了解 while 循环将创建多少个对象。
  • CLR是否可以动态增加应用程序分配的堆大小。
  • 并非所有对象都在 Gen0 中分配。大于 85000 字节的对象分配在大对象堆上。
  • 但这将是 LOH 而不是 SOH?我想 eash heap 有自己的 Gen0,Gen1 ......我错了吗?
  • 有两个逻辑堆。覆盖 Gen0 到 Gen2 和 LOH 的代堆。 LOH 的处理方式与分代堆非常不同。它不使用世代,不压缩,它使用类似于 crt 堆的空闲列表。
猜你喜欢
  • 2013-10-28
  • 2011-01-21
  • 2010-09-25
  • 2020-10-21
  • 1970-01-01
  • 1970-01-01
  • 2011-10-01
  • 2011-05-11
  • 2013-10-22
相关资源
最近更新 更多