Каков размер Nullable <Int32>?

Итак, на пару вопросов:

  • А int (Int32) указывается (очевидно) 32 бита. Как насчет int? (Nullable<int>)? Моя кишка говорит мне, что это будет 32 бита для целого числа плюс еще 8 бит для логического, но, возможно, реализация более сложная, чем эта.
  • Я бы ответил на свой вопрос, используя sizeof(int?); но поскольку int? является управляемым типом, это недопустимо. Я понимаю, что размер типа может быть зависимым от платформы, и что в случае объектов, содержащих ссылки на другие объекты, операция sizeof будет вводить в заблуждение. Однако существует ли способ получить "базовый" размер (т.е. Размер нового экземпляра экземпляра) для управляемого типа, учитывая текущую среду?

Ответ 1

Вы можете посмотреть в ildasm или рефлекторе.

Если имеет два поля: a bool и a T, возможно, 8 байтов (при условии выравнивания по 4 байт).

Ответ 2

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

Но так как вы все равно: минимальный размер - 0 байт. Что вы получите, когда оптимизатору JIT удастся сохранить значение в регистре CPU. Следующий размер - 2 байта, для bool? и байт?, 1 байт для HasValue, еще один байт для значения. Который вы редко получите, потому что локальные переменные должны быть выровнены с адресом, который кратен 4. Дополнительные 2 байта заполнения просто никогда не будут использоваться.

Следующий размер - 3 для краткости? и char?, теперь вы получите 1 байт заполнения.

Большой прыжок на следующий, int? требуется 5 байт, но заполнение увеличивает значение до 8.

Etcetera. Вы найдете это, написав немного кода, как это:

        int front = 42;
        bool? center = null;
        int back = 43;
        Console.WriteLine("", front, center, back);

И посмотрим инструкции машинного кода с отладчиком. Обратите внимание на смещения регистра ebp. И будьте осторожны, что стек растет.

Ответ 3

Я нашел обращение именно по этому вопросу здесь, в котором содержится код для простого консольного приложения для проверки использования памяти.

В принципе,

... Это означает, что тип с нулевым значением оболочке требуется 4 байта памяти...

Ответ 4

Рассмотрим метод Marshal.SizeOf. Он позволяет получить размер управляемых значений. Это странно, но похоже, что размер нулевого типа равен размеру их параметра типа (размер int равен размеру int и т.д.).