Узнайте размер a.net объект


Я пытаюсь выяснить, сколько памяти занимают мои объекты, чтобы увидеть, сколько из них попадает в большую кучу объектов (что составляет более 85 000 байт).

Это так же просто, как добавление 4 для int, 8 для long, 4 (или 8, если вы находитесь на 64 бит) для любых ссылочных типов и т. д. Для каждого объекта или есть накладные расходы для методов, свойств и т. д.

7   51   2008-11-27 18:38:10

7 ответов:

Не забывайте, что размер фактического объекта не включает размер любых объектов, на которые он ссылается.

единственными вещами, которые могут оказаться в большой куче объектов, являются массивы и строки - другие объекты, как правило, относительно малы сами по себе. Даже объект с (скажем) 10 ссылочными переменными типа (4 байта каждый на x86) и 10 GUID (16 байт каждый) будет занимать только около 208 байт (есть немного накладных расходов для ссылки на тип и синхронизации блок.)

аналогично, думая о размере массива, не забывайте, что если тип элемента является ссылочным типом, то это только размер ссылки это количество для самого массива. Другими словами, даже если у вас есть массив с 20 000 элементов, размер самого объекта массива будет только чуть более 80K (на x86), даже если он ссылается на гораздо больше данных.

пожалуйста, выполните следующие действия, чтобы получить размер объекта.

1) Перейдите в свойства проекта Visual Studio (2010) - > вкладка отладка - > включить отладку неуправляемого кода.

2) Перейдите в меню отладки Visual Studio - > параметры и настройки -> отладка -> символы.

3) там включите Microsoft Symbol Server,оставьте значение по умолчанию.(символы могут начать загрузку)

4) установите точку останова в коде, начните отладку(F5).

5) Открыть Debug - > Окна -> Окно "Интерпретация".

6) ввод .нагрузки СОС.dll (Son of Strike)

7) ввести !DumpHeap-тип MyClass (объект, который вы хотите найти размер)

8) из out put найдите адрес объекта т. е.(00a8197c)

размер MT адреса 00a8197c 00955124 36

9) Далее !ObjSize 00a8197c

10) там вы идете - > sizeof (00a8197c) = 12 (0x48) байт (MyClass)

вы попадаете в область расширенной отладки .NET. Начинаются с Джон Робинс отладка книг.

использовать WinDBG С Sos.dll (часть дистрибутива .NET) и Sosex.dll расширения. С помощью этих инструментов вы можете действительно видеть, что происходит, когда ваше приложение работает. Вы найдете ответы на вышеперечисленные вопросы.

(еще одна рекомендация будет установить общий источник CLI 2.0, также известный как. Ротор 2, чтобы посмотреть, что происходит под капотом.)

Если вы можете - сериализовать его!

Dim myObjectSize As Long

Dim ms As New IO.MemoryStream
Dim bf As New Runtime.Serialization.Formatters.Binary.BinaryFormatter()
bf.Serialize(ms, myObject)
myObjectSize = ms.Position

метод Гомеса упрощен:

  1. перейдите в свойства проекта Visual Studio (2010) - > вкладка отладка - > включить отладку неуправляемого кода.

  2. установите точку останова в коде, начните отладку (F5).

  3. Открыть Debug - > Windows - > Немедленное Окно.

  4. enter .загрузить sos

  5. enter (замените myObject именем вашего объекта)

? Строка.Формат ("{0: x}",целое число.Разбор(Системы.Во время выполнения.InteropServices.GCHandle.InternalAddrOfPinnedObject (System.Во время выполнения.InteropServices.GCHandle.Alloc ( myObject).GetHandleValue ()).Метод toString()) - 4)

6. Используйте результат как параметр !ObjSize

посмотреть: SOS.DLL, адрес объекта и отладчик Visual Studio Введение

пример (мы ищем объект с именем tbl):

.load sos
extension C:\Windows\Microsoft.NET\Framework\v4.0.30319\sos.dll loaded
? string.Format("{0:x}",Integer.Parse(System.Runtime.InteropServices.GCHandle.InternalAddrOfPinnedObject(System.Runtime.InteropServices.GCHandle.Alloc(tbl).GetHandleValue()).ToString())-4)
"27ccb18"
!ObjSize 27ccb18
PDB symbol for clr.dll not loaded
sizeof(027ccb18) =       154504 (     0x25b88) bytes (System.Data.DataTable)

Если это не огромный тип значения или тип экземпляра (т. е. многие тысячи полей), единственные типы, о которых вам нужно беспокоиться, - это большие массивы или строки. Конечно, чтобы выяснить размер массива, вам нужно знать размер элемента.

.NET (в настоящее время) выравнивает типы почти так же, как собственные компиляторы выравнивают типы. Фундаментальные типы имеют естественные выравнивания, которые обычно представляют собой округленную интегральную мощность двух ближайших к их размеру:

Single, Int32, UInt32 - 4
IntPtr, UIntPtr, pointers, references  - 4 on 32-bit, 8 on 64-bit
Double, Int64, UInt64 - 8
Char, Int16, UInt16   - 2
Byte, SByte           - 1

когда собирая тип, компилятор будет следить за тем, чтобы все поля любого данного типа имели начальное смещение в экземпляре, выровненное по границе, соответствующей этому типу, при условии, что явный макет не используется.

пользовательские типы сами имеют выравнивание, которое вычисляется как максимальное выравнивание любого из их типов полей. Размер типа расширяется, если это необходимо, чтобы выровнять размер типа.

но конечно, все ссылочные типы есть еще только IntPtr.Размер по размеру и выравниванию, поэтому размер ссылочного типа не будет влиять на массивы этого типа.

обратите внимание, что среда CLR может по своему усмотрению выбирать типы компоновки, отличные от описанных выше, возможно, чтобы увеличить локальность кэша или уменьшить заполнение, необходимое для выравнивания.

в качестве оценки (в 2017 году) вы можете отлаживать свое приложение, устанавливать точку останова до того, как ваш словарь начнет жить , сделать "снимок использования памяти" (вкладка: использование памяти в разделе "диагностические инструменты"), заполнить свой словарь и получить другой снимок - не точно поставить хороший жест.