sos.dll 返回的对象大小与内存中进程大小不匹配

发布于 2024-08-22 23:49:33 字数 478 浏览 6 评论 0原文

我使用以下 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.

I have used the following sos command to enumerate all instances of a particular type in a running asp application (hosted on windows xp 4 GB machine).

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

This enumerates all objects of the given type in gc gen2.

The object size on an average seems to be around 500 KB and there are around 2000 objects. This alone adds up to around 1 GB of memory whereas my asp-process memory in task manager shows only around 700 MB. One more point is that I haven't considered other loaded objects I am using.

Also all the above objects are root objects that will not be garbage collected. Not sure if this command is wrong or if there is any other explanation for this mismatch in size that sos returns and what is shown in task manager?

Thanks in advance,
Bharath K.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风蛊 2024-08-29 23:49:33

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

!objsize calculates the size of an instance including all its referenced objects, so if you have any objects that share references to other objects the size of these will be counted multiple times. The most common source for this is probably strings, as literal strings are interned and thus shared among objects using the same literal text. However, you may also have collections referencing the same objects. In any case, the sum will be incorrect unless the counted objects do not share any references at all.

Consider this example

class SomeType {
    private readonly string Text;

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

and this code

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");

In 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

As you can see from the output of !dumpobj, they both share the same reference, so if you sum the size as reported by !objsize above, the string is counted twice.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文