Что делает флаг JVM UseCompressedOops и когда его следует использовать?

85

Что делает флаг JVM HotSpot -XX:+UseCompressedOopsи когда его использовать? Какие различия в производительности и использовании памяти я увижу при использовании его на 64-битном экземпляре Java (а не при его неиспользовании)?

Ноальц
источник
1
Он сжимает 64-битные указатели. Вы увидите уменьшение объема памяти из-за увеличения размера указателя, меньшее время, затрачиваемое на сборку мусора, возможно, небольшое падение производительности. jdk1.6.0_22 была последней JVM Sun, у которой этот флаг отключен по умолчанию.
sjr

Ответы:

87

В большинстве JVM HotSpot за последний год он был включен по умолчанию. Этот параметр позволяет ссылкам быть 32-разрядными в 64-разрядной JVM и иметь доступ к куче размером около 32 ГБ. (может быть больше 32-битных указателей) (у вас также может быть почти неограниченная память вне кучи). Это может сэкономить значительный объем памяти и потенциально повысить производительность.

Если вы хотите использовать эту опцию, я предлагаю вам обновить ее до версии, в которой она включена по умолчанию, так как могла быть веская причина, например, ошибки, почему она не была включена ранее. Попробуйте Java 6 с обновлением 23 или Java 7 с обновлением 5.

Короче говоря, не включайте его, используйте версию, в которой он включен по умолчанию.


Обновить:

В Java 8 у вас есть возможность установить -XX:ObjectAlignmentInBytes=и на самом деле, если размер кучи равен 64 ГБ, он будет -XX:ObjectAlignmentInBytes=16использовать 32-разрядные ссылки.

Питер Лоури
источник
Я прочитал эту статью: community.oracle.com/message/10019916, в которой говорится, что мы всегда должны использовать этот флаг вручную, даже если он включен по умолчанию. Есть предположения?
vanval
1
@vanval Это рекомендуется, если вы используете JE cache Это потому, что по какой-то причине не может работать, используете ли вы компрессы. Я могу придумать несколько методов, которые помогут вам в этом. Вам не нужно указывать его в командной строке IMHO, если вы не хотите, чтобы JVM не работал, если он не включен. например, у вас есть куча 64 ГБ на Java 8.
Питер Лоури,
3
Я только что провел несколько тестов на Win8 x64 i7-4702MQ JDK 8 u40 с 7 ГБ xms и xmx, из 7 ГБ 5,4 ГБ используются большим деревом, загруженным из базы данных Access. Моя точка зрения: указание вручную флага -XX: + UseCompressedOops приводит к снижению производительности на 20% (при генерации большого дерева) и еще на 1 (с 3 до 4) длительную паузу GC (с GC по умолчанию). Вы воспринимаете это либо как снижение производительности, либо как увеличение паузы сборщика мусора. В любом случае, это было на 20% медленнее.
zmirc
1
Каждое приложение имеет собственный профиль памяти и использования. В нашем случае настольное приложение из 32-битного jvm, флаг + UseCompressedOops спасает положение, поскольку он сохраняет использование памяти на достаточно низком уровне, чтобы поместиться на старый клиентский компьютер емкостью 4 Гбайта, и повышает производительность на 30% по сравнению с 32-битным jvm.
Alex Byrth 09