Сколько байтов массив занимает в Java? Предположим, что это 64-битная машина, а также предположим, что в массиве есть N элементов, поэтому все эти элементы занимают 2 * N, 4 * N или 8 * N байт для разных типов массива.
И лекция в Coursera говорит, что она будет занимать 2 * N + 24, 4 * N + 24 или 8 * N + 24 байта для массива N элементов, а 24 байта называются издержками, но не объясняет, почему накладные расходы необходимо.
Также объекты имеют служебные данные, что составляет 16 байтов.
Что именно это накладные расходы? Из чего состоят эти 24/16 байтов?
Кроме того, эти накладные расходы существуют только в Java? Как насчет C, C ++ и Python?
Ответы:
Каждый объект Java имеет заголовок, который содержит информацию, важную для JVM. Наиболее важной является ссылка на класс объекта (одно машинное слово), и есть некоторые флаги, используемые сборщиком мусора и для управления синхронизацией (поскольку каждый объект может быть синхронизирован), который принимает другое машинное слово (использование частичных слов будет плохо для производительности). Таким образом, это 2 слова, что составляет 8 байтов в 32-битных системах и 16 байтов в 64-битных. Массивам дополнительно требуется поле int для длины массива, которая составляет еще 4 байта, возможно, 8 в 64-битных системах.
Что касается других языков:
C не имеет объектов, поэтому, конечно, он не имеет заголовков объектов - но может иметь заголовок на каждом отдельно выделенном фрагменте памяти.
В C ++ у вас нет сборщика мусора и вы не можете использовать произвольные объекты для синхронизации, но если у вас есть классы с переопределенными методами, каждый объект имеет указатель на свою vtable, так же как ссылка объекта Java на свой класс. Если вы используете умные указатели, которые выполняют сбор мусора, им нужны служебные данные.
Я не знаю насчет Python, но я почти уверен, что для него нужна ссылка на класс и служебная информация для сборщика мусора.
источник
std::pair<int, float>
это простой класс, который вообще не нуждается в vtable. В результате он может очень хорошо уместиться в 8 байтов. Кроме того, умные указатели на самом деле не нужно добавлять уборку. Яркий контр-примерstd::unique_ptr<T>
, который, как правило, такой же большой, как необработанныйT*
(unique_ptr, конечно, не делает GC).malloc
выделенный блок памяти нуждается в заголовке, которыйfree
затем использует.