Въведение в JVM кодовия кеш

1. Въведение

В този урок ще разгледаме набързо и ще научим за кеш паметта на кода на JVM.

2. Какво представлява кешът на кода?

Просто казано, JVM Code Cache е област, в която JVM съхранява своя байт код, компилиран в роден код . Ние наричаме всеки блок на изпълнимия роден код n-метод . В nmethod може да бъде пълен или inlined метод Java.

Компилаторът точно навреме (JIT) е най-големият потребител в областта на кеша на кода. Ето защо някои разработчици наричат ​​тази памет кеш за JIT код.

3. Настройка на кеша на кода

Кеш кодът има фиксиран размер . След като е пълен, JVM няма да компилира допълнителен код, тъй като JIT компилаторът вече е изключен. Освен това ще получим предупредителното съобщение „CodeCache е пълен ... Компилаторът е деактивиран “. В резултат на това ще получим влошена производителност в нашето приложение. За да избегнем това, можем да настроим кеша на кода със следните опции за размер:

  • InitialCodeCacheSize - размерът на кеша на първоначалния код, по подразбиране 160K
  • ReservedCodeCacheSize - максималният размер по подразбиране е 48MB
  • CodeCacheExpansionSize - размерът на разширението на кеша на кода, 32KB или 64KB

Увеличаването на ReservedCodeCacheSize може да бъде решение, но това обикновено е само временно решение.

За щастие JVM предлага опция UseCodeCacheFlushing за управление на измиването на областта на кеша на кода . Стойността му по подразбиране е false. Когато го активираме, той освобождава окупираната зона, когато са изпълнени следните условия:

  • кеш кодът е пълен; тази зона се измива, ако размерът й надвиши определен праг
  • определен интервал е преминал от последното почистване
  • предварително компилираният код не е достатъчно горещ. За всеки компилиран метод JVM следи специален брояч на горещината. Ако стойността на този брояч е по-малка от изчисления праг, JVM освобождава тази част от предварително компилиран код

4. Използване на кеш код

За да наблюдаваме използването на кеша на кода, трябва да проследим размера на използваната в момента памет.

За да получим информация за използването на кеш код, можем да посочим опцията –XX: + PrintCodeCache JVM . След като стартираме нашето приложение, ще видим подобен изход:

CodeCache: size=32768Kb used=542Kb max_used=542Kb free=32226Kb 

Нека да видим какво означава всяка от тези стойности:

  • size в изхода показва максималния размер на паметта, който е идентичен с ReservedCodeCacheSize
  • Използва се действителният размер на паметта, която в момента се използва
  • max_used е максималният размер, който е бил използван
  • безплатно е останалата памет, която все още не е заета

Опцията PrintCodeCache е много полезна, тъй като можем:

  • вижте кога зачервяването се случва
  • определете дали сме достигнали критична точка на използване на паметта

5. Сегментиран кеш на код

От Java 9 JVM разделя кеша на кода на три отделни сегмента, всеки от които съдържа определен тип компилиран код . За да бъдем по-конкретни, има три сегмента:

  • Неметодният сегмент съдържа JVM вътрешно свързан код, като интерпретатора на байт кода. По подразбиране този сегмент е около 5 MB. Също така е възможно да конфигурирате размера на сегмента чрез -XX: NonNMethodCodeHeapSize флаг за настройка
  • Сегментът с профилиран код съдържа леко оптимизиран код с потенциално кратък живот. Въпреки че размерът на сегмента е около 122 MB по подразбиране, можем да го променим чрез флаг за настройка -XX: ProfiledCodeHeapSize
  • Непрофилираният сегмент съдържа напълно оптимизиран код с потенциално дълъг живот. По същия начин това е около 122 MB по подразбиране. Тази стойност, разбира се, може да се конфигурира чрез -XX: NonProfiledCodeHeapSize флаг за настройка

Тази нова структура третира различните видове спазен код по различен начин, което води до по-добра цялостна производителност.

Например, разделянето на краткотраен компилиран код от дълготрайния код подобрява производителността на метода за почистване на метода - главно защото трябва да сканира по-малък регион памет.

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

Тази кратка статия представя кратко въведение в JVM кеша за кодове.

Освен това представихме някои опции за използване и настройка за наблюдение и диагностика на тази област на паметта.