!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
выше, строка подсчитывается дважды.