Что такое ReservedCodeCacheSize и InitialCodeCacheSize?

Может кто-нибудь, пожалуйста, объясните, что такое опция JVM ReservedCodeCacheSize а также InitialCodeCacheSize являются? В частности, когда / почему я хотел бы изменить это? Как я могу решить, какой правильный размер?

Вот что говорят доктора:

-XX: ReservedCodeCacheSize = 32m Зарезервированный размер кода (в байтах) - максимальный размер кода. [Solaris 64-bit, amd64 и -server x86: 2048m; в 1.5.0_06 и более ранних версиях, Solaris 64-bit и and64: 1024m.]

5 ответов

Решение

ReservedCodeCacheSize (а также InitialCodeCacheSize) является опцией для (точно вовремя) компилятора виртуальной машины Java Hotspot. По сути, он устанавливает максимальный размер кеша кода компилятора.

Кэш может быть заполнен, что приводит к следующим предупреждениям:

Java HotSpot(TM) 64-Bit Server VM warning: CodeCache is full. Compiler has been disabled.
Java HotSpot(TM) 64-Bit Server VM warning: Try increasing the code cache size using -XX:ReservedCodeCacheSize=
Code Cache  [0x000000010958f000, 0x000000010c52f000, 0x000000010c58f000)
 total_blobs=15406 nmethods=14989 adapters=362 free_code_cache=835Kb largest_free_block=449792

Это намного хуже, когда следуют Java HotSpot(TM) Client VM warning: Exception java.lang.OutOfMemoryError occurred dispatching signal SIGINT to handler- the VM may need to be forcibly terminated,

Когда установить эту опцию?

  1. при сбоях компилятора Hotspot
  2. уменьшить объем памяти, необходимый JVM (и, следовательно, рискнуть сбои JIT-компилятора)

Обычно вы бы не изменили это значение. Я думаю, что значения по умолчанию достаточно хорошо сбалансированы, потому что эти проблемы возникают только в очень редких случаях (в моем опыте).

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

Тем не менее, вы можете использовать jconsole, чтобы присоединиться к запущенному процессу Java, а затем использовать вкладку "Память", чтобы узнать размер кеша кода. Для полноты, шаги следующие (среда Linux VM, хотя я уверен, что другие среды похожи):

  1. Запустите jconsole на своей машине
  2. Найдите правильный идентификатор процесса и подключите к нему jconsole (это займет несколько минут)
  3. Перейдите на вкладку "Память"
  4. В раскрывающемся списке "Диаграмма:" выберите "Пул памяти" Кэш кода "".
  5. Опять же, это может занять несколько секунд для обновления экрана, а затем вы должны увидеть что-то вроде:изображение кэша кода jconsole

    Как видите, мой кэш кода использует около 49 МБ. На данный момент у меня все еще был стандарт, который указан в документации (и @jeha) 48 МБ. Конечно, отличная мотивация для меня, чтобы увеличить настройки!

    Бен.


    1024 МБ по умолчанию, вероятно, переусердствовали, но 48 МБ по умолчанию, кажется, переусердствовали...

Когда JVM компилирует код, он содержит набор инструкций на языке ассемблера в кеше кода. Кэш кода имеет фиксированный размер, и после его заполнения JVM не может скомпилировать дополнительный код.

Максимальный размер кеша кода задается с помощью флага -XX:ReservedCodeCacheSize=N (где N - это значение по умолчанию, упомянутое для конкретного компилятора). Кэш кода управляется так же, как и большая часть памяти в JVM: есть начальный размер ( -XX:InitialCodeCacheSize=N). Выделение размера кеша кода начинается с начального размера и увеличивается по мере заполнения кеша. Начальный размер кеша кода зависит от архитектуры чипа и используемого компилятора. Изменение размера кэша происходит в фоновом режиме и на самом деле не влияет на производительность, поэтому установка размера ReservedCodeCacheSize (т.е. установка максимального размера кэша кода) - это все, что обычно требуется.

По умолчанию для 64-битного сервера размер Java 7 составляет 48 МБ (для многоуровневой компиляции - 96 МБ). В Java 8 для 64-битного сервера объем памяти составляет 240 МБ.

- Пинаки

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

http://engineering.indeedblog.com/blog/2016/09/job-search-web-app-java-8-migration/

Вывод: Jdk 8 нужно больше кеша кода JDK 7

Размер кодового кэша по умолчанию для JRE 8 составляет около 250 МБ, что примерно в пять раз больше, чем 48 МБ по умолчанию для JRE 7. Наш опыт показывает, что JRE 8 нуждается в дополнительном кодовом кэше. На данный момент мы переключили около десяти сервисов на JRE 8, и все они используют примерно в четыре раза больше кодового кэша, чем раньше.

С https://blogs.oracle.com/poonam/entry/why_do_i_get_message:

Ниже приведены две известные проблемы в jdk7u4+, связанные с очисткой CodeCache:

  1. Компилятор может не перезапуститься даже после того, как загруженность CodeCache упадет почти до половины после аварийной очистки.
  2. Аварийная очистка может привести к высокой загрузке ЦП потоками компилятора, что приведет к общему снижению производительности.

Эта проблема производительности и проблема повторного включения компилятора была решена в JDK8. Чтобы обойти это в JDK7u4+, мы можем увеличить размер кэша кода, используя параметр ReservedCodeCacheSize, установив для него значение, превышающее размер компилируемого кода, чтобы CodeCache никогда не переполнялся. Другое решение этой проблемы - отключить очистку CodeCache с помощью опции -XX:-UseCodeCacheFlushing JVM.

Вышеупомянутые проблемы были исправлены в JDK8 и его обновлениях.

Так что эту информацию стоит упомянуть для систем, работающих на JDK 6 (с отключенной очисткой кода) и 7.

Другие вопросы по тегам