Несоответствие размера объекта, возвращаемого sos.dll, и размера процесса в памяти.

StackOverflow https://stackoverflow.com/questions/2316460

  •  22-09-2019
  •  | 
  •  

Вопрос

Я использовал следующую команду sos для перечисления всех экземпляров определенного типа в работающем приложении asp (размещенном на компьютере с Windows XP 4 ГБ).

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

Здесь перечислены все объекты данного типа в gc gen2.

Размер объекта в среднем составляет около 500 КБ, а объектов около 2000.Одно это добавляет около 1 ГБ памяти, тогда как моя память asp-процесса в диспетчере задач показывает только около 700 МБ.Еще один момент: я не учел другие загруженные объекты, которые использую.

Кроме того, все вышеперечисленные объекты являются корневыми объектами, которые не подлежат сборке мусора.Не уверены, что эта команда неверна или есть какое-то другое объяснение несоответствию размера, который возвращает sos, и того, что отображается в диспетчере задач?

Заранее спасибо,
Бхарат К.

Это было полезно?

Решение

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top