Я ищу способ получить размер экземпляра ссылочного типа. sizeof относится только к типам значений. Возможно ли это?
Sizeof() для ссылочных типов?
Ответ 1
Если вы не возражаете, что это немного менее точное, чем совершенное, и для сравнительных целей вы можете сериализовать объект /s и измерить его (например, в байтах)
EDIT (я продолжал думать после публикации): потому что это немного сложнее, чем sizeof для valuetypes, например: ссылочные типы могут иметь ссылки на другие объекты и т.д.... там нет точного и простого способа сделать это что я знаю...
Ответ 2
Вам нужно Marshal.SizeOf
Изменить: Это для небезопасного кода, но тогда это sizeof().
Ответ 3
Недавно у меня был аналогичный вопрос, и мне хотелось узнать размер Object и LinkedListNode в С#. Чтобы решить эту проблему, я разработал программу которая:
- Измерьте программу "Рабочий набор"
- Выделить много объектов.
- Снова замерьте "Рабочий набор".
- Разделите разницу на количество выделенных объектов.
На моем компьютере (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 байт. Эти данные иллюстрируют две вещи:
- Очень маловероятно, что система выделяет частичный байт. Дробная мера байтов указывает на накладные расходы, которые CLR требует для размещения и отслеживания миллионов ссылочных типов.
- Если мы просто округляем количество байтов, мы все же вряд ли будем иметь правильное количество байтов для ссылочных типов. Это ясно из измерения объектов. Если округлить, мы предположим, что размер составляет 29 байтов, что, теоретически возможно, маловероятно из-за заполнения. Чтобы повысить производительность, распределение объектов обычно дополняется для целей выравнивания. Я бы предположил, что объекты CLR будут выровнены по 4 байт.
Предполагая, что служебные данные CLR и 4-байтовое выравнивание, я бы оценил объект в С#, равный 28 байтам, а LinkedListNode - 44 байта.
Кстати, у Джона Скита была идея для метода выше, чем я это сделал, и заявил об этом в этом ответе к аналогичному вопросу.
Ответ 4
Помните, что Marshal.SizeOf предназначен для небезопасного кода...
Я не думаю, что это возможно для управляемого кода, хотя, может быть, вы можете объяснить свою проблему, может быть другой способ ее решить.
Ответ 5
Если вы можете - Сериализовать его!
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
Ответ 6
Пожалуйста, обратитесь к моему ответу в следующей ссылке.
Это возможно через расширение отладки .sos.dll