【问题标题】:Mismatch in object size returned by sos.dll and in-memory process sizesos.dll 返回的对象大小与内存中进程大小不匹配
【发布时间】:2010-02-23 07:43:06
【问题描述】:

我使用以下 sos 命令枚举了正在运行的 ASP 应用程序(托管在 windows xp 4 GB 机器上)中特定类型的所有实例。

.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 返回的大小不匹配以及任务管理器中显示的内容是否有任何其他解释?

提前致谢,
巴拉特·K。

【问题讨论】:

  • 您在任务管理器中查看的是什么计数器?
  • 顺便说一句 !dh 显示指定图像的标题。我猜你的意思是!dumpheap
  • 是的。它是!dumpheap。我在任务管理器中查看了内存使用情况和峰值内存使用情况。

标签: .net clr windbg sos


【解决方案1】:

!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 报告的大小相加,则该字符串被计算两次。

【讨论】:

  • 感谢 Rasmussen,我的每个对象都包含一个不同的 xml 文档,该文档由本质上唯一的表单(字符串)的定义构造而成。再次感谢伟大的洞察力。我将再次验证字符串是否确实被拘留,如果发生这种情况,我会将此问题标记为已关闭。
猜你喜欢
  • 2011-11-01
  • 2017-12-11
  • 2018-06-13
  • 1970-01-01
  • 2016-07-10
  • 2015-04-21
  • 1970-01-01
  • 2018-06-24
  • 1970-01-01
相关资源
最近更新 更多