2010-02-23 50 views
3

我已经使用以下sos命令来枚举正在运行的asp应用程序(托管在Windows xp 4 GB计算机上)中的特定类型的所有实例。由sos.dll和内存中进程大小返回的对象大小不匹配

.foreach (obj { !dumpheap -type ::my type:: -short ::start of address space:: ::end of address space:: }) { !objsize ${obj} }. 

这枚举了gc gen2中给定类型的所有对象。

对象大小平均为500 KB左右,大约有2000个对象。仅这一项就可以增加大约1 GB的内存,而我在任务管理器中的asp进程内存仅显示大约700 MB。还有一点是,我没有考虑我正在使用的其他加载的对象。

以上所有对象都是不会被垃圾收集的根对象。不确定这个命令是否有错,或者是否有任何其他解释说明sos返回的大小不匹配以及task manager中显示的内容?

由于提前,
巴拉斯K.

+0

你在任务管理器中查看什么计数器? – 2010-02-23 07:53:50

+0

Btw'!dh'显示指定图像的标题。我假设你的意思是'!dumpheap'。 – 2010-02-23 08:08:07

+0

是的。它是!dumpheap。我在任务管理器中查看了内存使用情况和内存使用情况峰值。 – 2010-02-23 08:18:00

回答

3

!objsize计算,包括其所有引用的对象实例的大小,所以如果你有共享引用到其他对象的任何对象的这些大小将被计入多个倍。最常见的来源可能是字符串,因为文字字符串被实施,因此使用相同的文本文本在对象之间共享。但是,您也可能拥有引用相同对象的集合。在任何情况下,除非所计算的对象根本不共享任何参考,否则总和将不正确。

考虑这个例子

class SomeType { 
    private readonly string Text; 

    public SomeType(string text) { 
     Text = text; 
    } 
} 

和验证码

var st1 = new SomeType("this is a long string that will be stored only once due to interning"); 
var st2 = new SomeType("this is a long string that will be stored only once due to interning"); 

WinDbg里

0:006> !dumpheap -type Some 
Address  MT  Size 
00ceb44c 00b738a8  12  
00ceb458 00b738a8  12  

0:006> !objsize 00ceb44c 
sizeof(00ceb44c) =   164 (  0xa4) bytes (TestApp.SomeType) 
0:006> !objsize 00ceb458 
sizeof(00ceb458) =   164 (  0xa4) bytes (TestApp.SomeType) 

0:006> !DumpObj 00ceb44c 
Name:  TestApp.SomeType 
MethodTable: 00b738a8 
EEClass:  00b714bc 
Size:  12(0xc) bytes 
File:  c:\dev2010\FSharpLib\TestApp\bin\Release\TestApp.exe 
Fields: 
     MT Field Offset     Type VT  Attr Value Name 
79b9d2b8 4000001  4  System.String 0 instance 00ceb390 Text 
0:006> !DumpObj 00ceb458 
Name:  TestApp.SomeType 
MethodTable: 00b738a8 
EEClass:  00b714bc 
Size:  12(0xc) bytes 
File:  c:\dev2010\FSharpLib\TestApp\bin\Release\TestApp.exe 
Fields: 
     MT Field Offset     Type VT  Attr Value Name 
79b9d2b8 4000001  4  System.String 0 instance 00ceb390 Text 

正如你可以从!dumpobj输出看到的,他们都有着相同的参考,所以如果你按上面!objsize报告的大小求和,字符串就是c安装了两次。

+0

谢谢Rasmussen,我的每个对象都包含一个独特的xml文档,它是从本质上独特的窗体(字符串)的定义构造而来的。再次感谢伟大的洞察力。我会再次验证字符串是否确实被拦截,并在这种情况下将此问题标记为已关闭。 – 2010-02-23 09:40:36