堆内存管理.Net

时间:2011-12-12 19:12:57

标签: c# .net memory stack heap

创建2个相同类型的对象时,堆栈内存中的句柄是指向堆中的同一个对象,还是指向2个单独的对象。为清楚起见,这是具体的问题......

class Q2 {
   private static int num = 0;
   private String prefix;

   public Q2 (String p)
    { prefix = p; }

   public String Msg (String str) {
      String n;
      num++;   
      n = num.ToString();
     return n + " - " + prefix + str;
   }
}

使用适当的图表,描述执行完所有以下语句后的内存状态。

 Q2 var1, var2;
   var1 = new Q2("Question 2");
   var2 = new Q2 ("Another view");

以下是我无法决定的答案:

1个对象:

enter image description here

2个对象:

enter image description here

4 个答案:

答案 0 :(得分:4)

为了帮助澄清有关堆的讨论,CLR使用了大约8种不同的堆:

  1. Loader Heap:包含CLR结构和类型系统
  2. 高频堆:静态,MethodTables,FieldDescs,界面图
  3. 低频堆:EEClass,ClassLoader和查找表
  4. Stub Heap:CAS,COM包装器,P / Invoke
  5. 的存根
  6. 大对象堆:需要超过85k字节的内存分配
  7. GC堆:用户为应用分配了专用的堆内存
  8. JIT代码堆:由mscoreee(执行引擎)分配的内存和托管代码的JIT编译器
  9. 进程/基本堆:互操作/非托管分配,本机内存等
  10. HTH

答案 1 :(得分:3)

您正在使用new关键字在两个单独的变量中实例化对象,因此,这总是在堆上创建新对象。所以答案是它总是指向两个独立的对象。

修改: 静态变量(如num)存储在名为High Frequency Heap的堆上的特殊区域中,而不是由垃圾收集器等收集。

答案 2 :(得分:2)

From MSDN

  

无论创建了多少个类实例,都只存在一个静态成员的副本。

所以,因为你的类是非静态的,你最终会得到你的类的多个实例,但它们将引用相同的,单一的,共享的静态成员实例。

注意:你应该非常小心上面的代码,因为最终可能会有多个类实例改变共享静态成员的值,这会导致不可预见的行为,竞争条件,损坏等等。

如果您的意图是将该类作为共享单例,那么将该类本身标记为静态,这样您在任何时候都只能在堆中拥有一个。

答案 3 :(得分:1)

.Net永远不会自动组合类似的对象。