2012-08-02 97 views
2
统计输出

说我有以下类:了解大对象堆和DumpHeap

Class A 
{ 
B b; 
C c; 
D d; 
} 

首先,我分配:

var b1 = new B(); 
var c1 = new C(); 
var d1 = new D(); 

每个b1, c1, d1小于85K,使他们获得分配上小物件堆。 后来我做:

var a1 = new A { b = b1, c = c1, d = d1 }; 

问题1:当我做!DumpHeap -stat确实的A内存使用包括由它的成员变量占用的内存?如果不是,它实际上包含了什么?
编辑:在这篇文章中找到了这个问题的答案:http://blogs.msdn.com/b/tess/archive/2005/11/25/dumpheap-stat-explained-debugging-net-leaks.aspx。这是有道理的,内存使用A不包括内存占用b1, c1, d1。它包括存储b1, c1, d1引用本身所需的内存。

问题2:a1是否在大对象堆上分配(假定大小为b1 + c1 + d1> 85K)?为什么?参考文献b1, c1, d1指向小物体堆上的物体。那么为什么a1坐在蕙?

问题3:让我们翻转它。说b1的大小是超过85K,所以它分配在LOH上。但要存储对b1, c1, d1的引用,我们只需要几个字节。我是否相信a1将被分配在小对象堆上?

回答

1

1)由于您已经发现A实例的大小不包括引用对象的大小。但是,如果要查找大小,请使用!objsize命令。请记住,如果多个对象引用相同的其他对象,则这些对象的大小将被多次包含。

2)a1引用的对象没有分配到LOH。该对象本身小于85000字节,因此它分配在常规堆上。使用!gcwhere命令列出给定对象所在堆的哪部分。

3)b1引用指向一个大对象时无关紧要。 A的任何实例的大小将只有三个引用加上一些额外的开销(对类型对象和同步块的引用)。即大小将远离LOH限制。