Рубрики
Без рубрики

boolean и boolean» Память Layout в JVM

Узнайте след boolean значение в JVM в различных обстоятельствах

Автор оригинала: Ali Dehghani.

1. Обзор

В этой быстрой статье мы увидим, каков след булеан значение в СПМ в различных обстоятельствах.

Во-первых, мы проинспектировать JVM, чтобы увидеть размеры объекта. Тогда мы поймем обоснование этих размеров.

2. Настройка

Для проверки макета памяти объектов в JVM мы собираемся использовать макет объекта Java ( ДЖОЛ ) широко. Поэтому нам нужно добавить jol-core зависимость:


    org.openjdk.jol
    jol-core
    0.10

3. Размеры объектов

Если мы попросим JOL распечатать детали VM с точки зрения размеров объектов:

System.out.println(VM.current().details());

Когда сжатые ссылки включены (поведение по умолчанию), мы увидим выход:

# Running 64-bit HotSpot VM.
# Using compressed oop with 3-bit shift.
# Using compressed klass with 3-bit shift.
# Objects are 8 bytes aligned.
# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

В первых нескольких строках мы можем увидеть некоторую общую информацию о VM. После этого мы узнаем о размерах объектов:

  • Java ссылки потребляют 4 байта, булеан s/ byte s 1 byte, char s/ короткие s 2 байта, int s/ поплавок s 4 байта, и, наконец, долго s/ двойной s 8 байтов
  • Эти типы потребляют одинаковое количество памяти, даже когда мы используем их в качестве элементов массива

Таким образом, в присутствии сжатых ссылок, каждый булеан значение занимает 1 byte. Аналогичным образом, каждый булеан в булеане потребляет 1 byte. Тем не менее, выравнивание обивки и заготовки объектов может увеличить пространство, потребляемое булеан и булеане как мы увидим позже.

3.1. Нет сжатых ссылок

Даже если мы отключим сжатые ссылки через -XX:-UseCompressedOops , размер boolean не изменит на всех :

# Field sizes by type: 8, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
# Array element sizes: 8, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

С другой стороны, ссылки Java берут в два раза больше памяти.

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

3.2. Слово Разрыв

В большинстве архитектур нет способа получить доступ к одному биту атоманно. Даже если бы мы хотели сделать это, мы, вероятно, в конечном итоге писать на соседние биты при обновлении другого.

Одной из целей СПМ является предотвращение этого явления, известного как слово разрывая . То есть в СПМ каждая область и элемент массива должны быть отдельными; обновления одного поля или элемента не должны взаимодействовать с чтениями или обновлениями какого-либо другого поля или элемента.

Напомним, вопросы адресности и разрыва слов являются основными причинами, по которым булев s больше, чем просто один бит.

4. Обыкновенные указатели объектов (OOPs)

Теперь, когда мы знаем булеан s 1 byte, рассмотрим этот простой класс:

class BooleanWrapper {
    private boolean value;
}

Если мы проверяем макет памяти этого класса с помощью JOL:

System.out.println(ClassLayout.parseClass(BooleanWrapper.class).toPrintable());

Затем JOL распечатает макет памяти:

 OFFSET  SIZE      TYPE DESCRIPTION                               VALUE
      0    12           (object header)                           N/A
     12     1   boolean BooleanWrapper.value                      N/A
     13     3           (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 3 bytes external = 3 bytes total

BooleanWrapper макет состоит из:

  • 12 байтов для заголовка, в том числе два марк слова и один Класс слово. СПМ HotSpot использует марк слово для хранения метаданных GC, хэш-кода идентификации и информации о блокировке. Кроме того, он использует Класс слово для хранения метаданных класса, таких как проверки типа времени выполнения
  • 1 тотализатор для фактического булеан ценность
  • 3 байта обивки для выравнивания целей

По умолчанию ссылки на объекты должны быть выровнены на 8 байтов. Таким образом, JVM добавляет 3 байта до 13 байтов заголовка и булеан чтобы сделать его 16 байтов.

Поэтому булеан поля могут потреблять больше памяти из-за их выравнивания поля.

4.1. Пользовательское выравнивание

Если мы изменим значение выравнивания до 32 через -XX:ОбъектПовинениеInBytes-32, затем один и тот же макет класса изменяется на:

OFFSET  SIZE      TYPE DESCRIPTION                               VALUE
      0    12           (object header)                           N/A
     12     1   boolean BooleanWrapper.value                      N/A
     13    19           (loss due to the next object alignment)
Instance size: 32 bytes
Space losses: 0 bytes internal + 19 bytes external = 19 bytes total

Как показано выше, JVM добавляет 19 байтов обивки, чтобы сделать размер объекта кратным 32.

5. Массив OOPs

Давайте посмотрим, как JVM излагает булеан массив в памяти:

boolean[] value = new boolean[3];
System.out.println(ClassLayout.parseInstance(value).toPrintable());

Это будет печатать макет экземпляра следующим образом:

OFFSET  SIZE      TYPE DESCRIPTION                              
      0     4           (object header)  # mark word
      4     4           (object header)  # mark word
      8     4           (object header)  # klass word
     12     4           (object header)  # array length
     16     3   boolean [Z.    # [Z means boolean array                        
     19     5           (loss due to the next object alignment)

В дополнение к двум марк слова и один Класс слово, массив указатели содержат дополнительные 4 байта для хранения их длины.

Так как наш массив имеет три элемента, размер элементов массива составляет 3 байта. Тем не менее, эти 3 байта будут проложены 5 байтами выравнивания поля для обеспечения надлежащего выравнивания.

Хотя каждый булеан элемент в массиве составляет всего 1 тотализатор, весь массив потребляет гораздо больше памяти. Другими словами, мы должны рассмотреть заголовок и обивка накладных расходов при вычислении размера массива.

6. Заключение

В этом быстром учебнике, мы увидели, что булеан поля потребляют 1 byte. Кроме того, мы узнали, что мы должны рассмотреть заголовок и обивка накладных расходов в размерах объектов.

Для более подробного обсуждения настоятельно рекомендуется проверить Упс раздел СПМ исходный код. Кроме того, Алексей Шипилов имеет гораздо более углубленные статьи в этой области.

Как обычно, все примеры доступны более на GitHub .