Мне нужно больше места, чем комментарию, чтобы расширить выводы Марио, поэтому вместо этого я добавлю ответ.
Размер C union
будет размером его наибольшего члена (возможно, с дополнительными байтами для удовлетворения ограничений выравнивания). Для zvalue_value
это будет obj
, который имеет размер трех указателей (не включая память, требуемую для того, на что указывают эти указатели):
typedef struct _zend_object {
zend_class_entry *ce;
HashTable *properties;
HashTable *guards; /* protects from __get/__set ... recursion */
} zend_object;
В 32-битной системе zend_object
займет 24 байта, а в 64-битной системе - 48 байтов. Таким образом, каждый zvalue_value
будет занимать не менее 24 или 48 байтов независимо от того, какие данные вы в нем храните. Также есть имя переменной, которая потребляет больше памяти; Скомпилированные языки обычно отбрасывают имена после завершения компиляции и обрабатывают значения как простые последовательности байтов (поэтому double
занимает восемь байтов, char
занимает один байт и т. д.).
Что касается ваших недавних вопросов о логических значениях PHP, простое логическое значение будет использовать 24 или 48 байт для значения, плюс еще несколько байтов для имени, плюс четыре или восемь для zend_unit
, плюс четыре (или восемь) для двух zend_uchar
в этом:
struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */
zend_uint refcount__gc;
zend_uchar type; /* active type */
zend_uchar is_ref__gc;
};
Члены zend_uchar
будут жевать четыре (или восемь) байта из-за ограничений выравнивания, почти каждый ЦП хочет получить доступ к памяти на границах естественных адресов, а это означает, что элемент размером в 10 байт struct
займет четыре байта или восемь байтов памяти (в зависимости от естественного размера слова CPU и ограничений выравнивания). Таким образом, логическое значение займет от 36 до 72 байт памяти.