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

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

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

Ответ 1

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

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

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

Ответ 2

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

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

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

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

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

5) Откройте Debug → Windows → Немедленное окно.

6) введите .load sos.dll(Сын забастовки)

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

8) из out put определяют адрес объекта i.e(00a8197c)

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

9) Далее, ObjSize 00a8197c

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

Ответ 3

Вы попадаете в область расширенной отладки .NET. Начните с John Robins отлаживает книги.

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

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

Ответ 4

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

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

Ответ 5

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

  • перейти в Visual Studio (2010) Свойства проекта → вкладка отладки → включить неуправляемую отладку кода.

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

  • Откройте Debug → Windows → Немедленное окно.

  • введите .load sos

  • введите (замените myObject на имя вашего объекта)

? String.Format( "{0: х}"., Integer.Parse(System.Runtime.InteropServices.GCHandle.InternalAddrOfPinnedObject(System.Runtime.InteropServices.GCHandle.Alloc(MyObject).GetHandleValue()) ToString()) - 4)

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

см. SOS.DLL, объект Address и отладчик 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)

Ответ 6

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

.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.Size по размеру и выравниванию, поэтому размер ссылочного типа не влияет на массивы этого типа.

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

Ответ 7

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