Пример в этой статье описывает, как вычислить (или оценить) объем памяти, занимаемый объектом Java. Поделитесь этим со всеми для справки. Конкретный анализ заключается в следующем:
Обычно мы говорим об использовании динамической памяти в контексте «общих случаев». Следующие две ситуации не включены:
В некоторых случаях JVM вообще не помещает объект в кучу. Например: В принципе, небольшой локальный объект потока существует в стеке, а не в куче.
Объем памяти, занимаемой Объектом, зависит от текущего состояния Объекта. Например: действует ли блокировка синхронизации Объекта или перерабатывается ли Объект.
Давайте сначала посмотрим, как выглядит один объект в куче.
В куче каждый объект состоит из четырех полей (A, B, C и D). Давайте объясним каждое из них ниже:
A: Заголовок объекта, который занимает очень мало байт и выражает информацию о текущем состоянии объекта.
B: Пространство, занимаемое полями базового типа (собственные поля относятся к int, boolean, short и т. д.).
C: Пространство, занимаемое полями ссылочного типа (поля ссылочного типа относятся к ссылкам на другие объекты, каждая ссылка занимает 4 байта)
D: Пространство, занимаемое наполнителем (что такое наполнитель, будет объяснено позже)
Ниже мы объясним A, B, C и D одно за другим.
A: Заголовок объекта
В памяти общее пространство, занимаемое каждым объектом, включает не только пространство, необходимое для переменных, объявленных внутри объекта, но также включает некоторую дополнительную информацию, такую как заголовки объектов и заполнители. Функция «заголовка объекта» заключается в записи имени экземпляра, идентификатора и статуса экземпляра объекта (например, является ли текущий экземпляр «достижимым», или состояния текущей блокировки и т. д.).
В текущей версии JVM (Hotspot) количество байт, занимаемых «заголовком объекта», следующее:
Обычный объект, занимающий 8 байт
Массив, занимает 12 байт, из них 8 байт + 4 байта обычных объектов (длина массива)
Б: базовый тип
boolean и byte занимают 1 байт, char и short занимают 2 байта, int и float занимают 4 байта, long и double занимают 8 байтов.
C: ссылочный тип
Каждый ссылочный тип занимает 4 байта.
Д: наполнитель
В Hotspot общее пространство, занимаемое каждым объектом, рассчитывается как кратное 8. Когда общее пространство, занимаемое объектом (заголовок объекта + объявленные переменные), меньше кратного 8, оно будет заполнено автоматически. Однако эти заполненные пространства можно назвать «наполнителями». Давайте рассмотрим конкретный пример:
Пустой объект (без объявленных переменных) занимает 8 байт --> заголовок объекта занимает 8 байт.
Класс, который объявляет только одну переменную логического типа, занимает 16 байт --> заголовок объекта (8 байт) + логическое значение (1 байт) + заполнитель (7 байт).
Класс, который объявляет 8 переменных логического типа, занимает 16 байт --> заголовок объекта (8 байт) + логическое значение (1 байт) * 8.
Приведенные выше примеры помогут нам углубить понимание программирования на Java.