Что такое ReservedCodeCacheSize и InitialCodeCacheSize?
Может кто-нибудь объяснить, что такое опция JVM ReservedCodeCacheSize
и InitialCodeCacheSize
? В частности, когда/почему я хочу его изменить? Как я могу решить, какой правильный размер?
Это то, что говорят документы:
-XX: ReservedCodeCacheSize = 32m Размер кэша зарезервированного кода (в байтах) - максимальный размер кеша кода. [Solaris 64-bit, amd64 и -сервер x86: 2048m; в 1.5.0_06 и ранее, Solaris 64-bit и and64: 1024m.]
Ответы
Ответ 1
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
.
Когда установить эту опцию?
- при наличии сбоев компилятора Hotspot
- чтобы уменьшить память, необходимую JVM (и, следовательно, риск сбоев компилятора JIT)
Обычно вы не изменяете это значение. Я думаю, что значения по умолчанию довольно хорошо сбалансированы, потому что эти проблемы возникают только в очень редких случаях (в моем опыте).
Ответ 2
@jeha отвечает на все, что я хотел знать из этого вопроса, кроме того, какое значение нужно задать для параметров. Поскольку я не писал код, который я развертывал, у меня не было заметной видимости в области памяти, которую он имел.
Однако вы можете использовать jconsole для присоединения к вашему запущенному Java-процессу, а затем использовать вкладку "Память", чтобы узнать размер кеша кода. Для полноты, шаги (среда Linux VM, хотя я уверен, что другие среды схожи):
- Запустите jconsole на вашем компьютере.
- Найдите правильный идентификатор процесса и прикрепите к нему jconsole (это займет несколько секунд)
- Перейдите на вкладку "Память"
- В раскрывающемся списке "Диаграмма:" выберите "Кодовый кеш памяти" "
-
Опять же, для обновления экрана может потребоваться несколько секунд, и тогда вы увидите что-то вроде:
![jconsole code cache image]()
Как вы можете видеть, в моем кеше кода используется около 49 МБ. На данный момент у меня все еще есть значение по умолчанию, которое говорит документация (и @jeha) - 48 МБ. Конечно, отличная мотивация для меня, чтобы увеличить настройку!
Бен.
1024 Мбайт по умолчанию, вероятно, переусердствовал, но 48 Мбайт по умолчанию, кажется, недооценивают его...
Ответ 3
Когда JVM компилирует код, он содержит набор инструкций на языке ассемблера в
кеш кода. Кэш кода имеет фиксированный размер, и как только он заполняется, JVM не
способный скомпилировать любой дополнительный код.
Максимальный размер кеша кода устанавливается с помощью символа -XX: ReservedCodeCacheSize = N
(где N - значение по умолчанию, указанное только для конкретного компилятора). Кэш кода
как и большинство памяти в JVM: есть начальный размер (
-XX: InitialCodeCacheSize = N). Распределение размера кеша кода начинается с начального
размер и увеличивается по мере заполнения кеша. Исходный размер кеша кода зависит от
архитектуры чипа и используемого компилятора. Изменение размера
кеш происходит в фоновом режиме и не влияет на производительность, поэтому настройка
Размер ReservedCodeCacheSize (т.е. Установка максимального размера кеша кода) - это все, что
как правило, требуется.
По умолчанию для 64-битного сервера размер Java 7 составляет 48 МБ (с многоуровневой компиляцией его 96 МБ). В Java 8 для 64-битного сервера размер памяти составляет 240 МБ.
- Пинаки
Ответ 4
Хороший опыт обучения от команды инженеров и проблем, с которыми они столкнулись при переходе на jdk 8.
http://engineering.indeedblog.com/blog/2016/09/job-search-web-app-java-8-migration/
Заключение: Jdk 8 нуждается в дополнительном кеше кода han JDK 7
Размер кодека по умолчанию для JRE 8 составляет около 250 МБ, что примерно в пять раз больше, чем по умолчанию 48 МБ для JRE 7. Наш опыт в том, что JRE 8 нуждается в дополнительном кодеке. До сих пор мы включили около 10 сервисов в JRE 8, и все они используют примерно в четыре раза больше кодеков, чем раньше.
Ответ 5
из https://blogs.oracle.com/poonam/entry/why_do_i_get_message:
Ниже приведены две известные проблемы в jdk7u4 + относительно сброса CodeCache:
- Компилятор не может быть перезапущен даже после того, как загрузка CodeCache упадет почти до половины после аварийного сброса.
- Аварийная промывка может привести к высокому использованию ЦП в потоках компилятора, что приведет к ухудшению общей производительности.
Эта проблема производительности и проблема компилятора, не получающего повторного включения снова, были рассмотрены в JDK8. Чтобы обойти их в JDK7u4 +, мы можем увеличить размер кеша кода с помощью параметра ReservedCodeCacheSize, установив его на значение, большее, чем размер скомпилированного кода, чтобы CodeCache никогда не заполнялся. Другим решением является отключить очистку CodeCache с помощью опции -XX: -UseCodeCacheFlushing JVM.
Вышеупомянутые проблемы были исправлены в JDK8 и его обновлениях.
Таким образом, эту информацию можно было бы упомянуть для систем, работающих на JDK 6 (с отключением кода) и 7.