эквивалентность sizeof () для ссылочных типов? - PullRequest
20 голосов
/ 25 августа 2008

Я ищу способ получить размер экземпляра ссылочного типа. sizeof только для типов значений. Возможно ли это?

Ответы [ 6 ]

12 голосов
/ 25 августа 2008

Вам нужно Marshal.SizeOf

Редактировать: Это для * небезопасного кода , но также sizeof ().

10 голосов
/ 25 августа 2008

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

РЕДАКТИРОВАТЬ (я продолжал думать после публикации) : Потому что это немного сложнее, чем sizeof для типов значений, например: ссылочные типы могут иметь ссылки на другие объекты и так далее ... нет точного и простой способ сделать это, о котором я знаю ...

4 голосов
/ 12 июля 2011

У меня недавно был похожий вопрос, и я хотел узнать размер Object и LinkedListNode в C #. Чтобы решить эту проблему, я разработал программу , которая бы:

  1. Измерение "рабочего набора" программы
  2. Выделите много объектов.
  3. Снова измерить «рабочий набор».
  4. Разделите разницу на количество выделенных объектов.

На моем компьютере (64-разрядном) я получил следующие данные:

Measuring Object:
iter    working set     size estimate
-1      11190272
1000000 85995520        74.805248
2000000 159186944       73.998336
3000000 231473152       73.4276266666667
4000000 306401280       73.802752
5000000 379092992       73.580544
6000000 451387392       73.3661866666667
7000000 524378112       73.3125485714286
8000000 600096768       73.613312
9000000 676405248       73.9127751111111
Average size: 73.7577032239859
Measuring LinkedListNode<Object>:
iter    working set     size estimate
-1      34168832
1000000 147959808       113.790976
2000000 268963840       117.397504
3000000 387796992       117.876053333333
4000000 507973632       118.4512
5000000 628379648       118.8421632
6000000 748834816       119.110997333333
7000000 869265408       119.299510857143
8000000 993509376       119.917568
9000000 1114038272      119.985493333333
Average size: 118.296829561905
Estimated Object size: 29.218576886067
Estimated LinkedListNode<reference type> size: 44.5391263379189

Исходя из данных, средний размер выделения миллионов объектов составляет примерно 29,2 байта. Объект LinkedListNode составляет приблизительно 44,5 байта. Эти данные иллюстрируют две вещи:

  1. Маловероятно, что система выделяет частичный байт. Дробная мера байтов указывает накладные расходы, которые требуются CLR для выделения и отслеживания миллионов эталонных типов.
  2. Если мы просто округлим количество байтов, у нас все равно вряд ли будет правильное количество байтов для ссылочных типов. Это ясно из меры объектов. Если мы округляем вниз, мы предполагаем, что размер составляет 29 байтов, что, хотя теоретически возможно, маловероятно из-за заполнения. Чтобы улучшить производительность, распределение объектов обычно дополняется для выравнивания. Я предполагаю, что объекты CLR будут выровнены на 4 байта.

Принимая во внимание издержки CLR и 4-байтовое выравнивание, я бы оценил Object в C # как 28 байт, а LinkedListNode - 44 байта.

Кстати, Джон Скит придумал способ, описанный выше, до того, как я это сделал, и изложил в этом ответе на аналогичный вопрос.

1 голос
/ 19 августа 2011

Пожалуйста, обратитесь мой ответ по ссылке ниже.

Это возможно через расширение отладчика .sos.dll

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

1 голос
/ 05 июля 2011

Если можешь - сериализуй!

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 голос
/ 25 августа 2008

Остерегайтесь, что Marshal.SizeOf для небезопасного кода ...

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...