Подтвердить что ты не робот

Уловка за JVM сжата Упс

Итак, я понимаю, что сжатые oops включены по умолчанию в HotSpot VM. Он поддерживает это с Java SE 6u23 и затем через опцию VM -XX:+UseCompressedOops. Я понимаю, что он позволяет эффективно использовать кэш ЦП, поскольку кэширование ЦП может содержать больше ссылок, чем если бы им приходилось иметь дело с 64-разрядными ссылками. Но то, что я не понимаю, заключается в том, что использование только 32-разрядных JVM может адресовать до 2 адресов 64.

Чтобы упростить задачу, как мы можем адресовать адрес памяти до 2 4 используя только 2 бита? Каким может быть возможное кодирование/декодирование такой адресной схемы?

4b9b3361

Ответ 1

Подробное объяснение сжатых oops см. в статье "Сжатый опечаток в Hotspot JVM" от John Rose @Oracle.

Версия TL; DR:

  • на современных компьютерных архитектурах, адреса памяти - это байтовые адреса,
  • Ссылки на объекты Java - это адреса, указывающие на начало слова 1,
  • на 64-битной машине выравнивание слов означает, что нижние 3 бита ссылки/адреса объекта равны нулю 2
  • поэтому, сдвинув адрес на 3 бита вправо, мы можем "сжать" до 35 бит 64-битного адреса в 32-битное слово,
  • и декомпрессию можно сделать, сдвинув 3 бита влево, что возвращает эти 3 нулевых бита,
  • 35 бит адресации позволяют нам представлять указатели объектов до 32 Гбайт памяти кучи, используя сжатые oops, которые соответствуют 32-разрядным (полу-) словам на 64-битной машине.

Обратите внимание, что этот только работает на 64-разрядной JVM. Нам все еще нужно иметь возможность адресовать память, содержащую эту (до) 32 ГБ кучу 1 а это означает 64-разрядные аппаратные адреса (на современных процессорах/компьютерных архитектурах).

Обратите также внимание, что при этом есть небольшой штраф; т.е. инструкции сдвига, необходимые для перевода между регулярными и сжатыми ссылками. Однако обратная сторона заключается в том, что потребляется менее актуальная память 3 и, как следствие, кэши памяти обычно более эффективны.

1 - Это связано с тем, что современные компьютерные архитектуры оптимизированы для доступа к памяти с выравниванием по словам.

2 - Предполагается, что вы не использовали -XX:ObjectAlignmentInBytes, чтобы увеличить выравнивание от его значения по умолчанию (и минимум) 8 байтов.

3 - Фактически, сохранение памяти зависит от приложения. Это зависит от средней потери выравнивания объекта, отношения ссылки к полям без ссылки и т.д. Это становится более сложным, если вы рассматриваете настройку выравнивания объекта.


Чтобы упростить задачу, как мы можем адресовать до 2 адресов 4 используя только 2 бита? Каким может быть возможное кодирование/декодирование такой адресной схемы?

Вы не можете адресовать адреса 2 4. Но вы можете адресовать 2 2 слова адреса (предполагая 32-разрядные слова), используя 2-битные слова. Если вы можете предположить, что все байтовые адреса выровнены по слову, вы можете сжимать 4-битный адрес байта в виде 2-битного слова, сдвигая его на 2-битные позиции.

Ответ 2

Он не предназначен для 32-разрядных JVM. Это облегчает дополнительные накладные расходы, возникающие в 64-битных JVM. Я думаю, что страница Oracle объясняет это хорошо:

Сжатый образ

Сжатый указатели (во многих, но не во всех местах программного обеспечения JVM), как 32-разрядные смещение объекта из 64-разрядного базового адреса кучи Java. Потому что они смещения объектов, а не байтовые смещения, их можно использовать для адресации до четырех миллиардов объектов (не байтов) или размер кучи до примерно 32 гигабайта. Чтобы использовать их, их необходимо масштабировать в 8 раз и добавлен в базовый адрес кучи Java, чтобы найти объект, к которому они см.

источник

Ответ 3

CompressedOops.

Из статьи: Не все указатели сжаты, а сжатые - 32-битные значения, которые необходимо масштабировать в 8 раз и добавлять к 64-разрядному базовому адресу, чтобы найти объект, на который они ссылаются.

Теперь обратите внимание, что вы не можете адресовать 2 ^ 64 бит памяти с этими 32-битными указателями, но вы можете получить доступ к ним с помощью Objects. Если у вас есть объект в ячейке памяти x, вы не можете найти другой объект в x+1. Поэтому вам не нужно получать доступ к каждой отдельной ячейке памяти.

Ответ 4

https://blog.codecentric.de/en/2014/02/35gb-heap-less-32gb-java-jvm-memory-oddities/

Я думаю, что эта статья объясняет это хорошо. Снято:

Поскольку компоновка памяти JVM использует 8-байтовую схему адресации, что означает, что объекты могут быть по адресу 0, 8, 16, 24… но не по адресу 2, 7 или любому другому, не кратному 8, сжатые упы просто обращаются к виртуальным позициям 0, 1, 2, 3 вместо реальных 0, 8, 16, 24. Чтобы перейти от сжатого адреса к реальному, JVM нужно просто сдвинуть его влево 3 раза. Легко.

4G * 8 = 32