Java 8: от PermGen к MetaSpace

в 18:26, , рубрики: java, java 8, metaspace, permgen

(Сокращённый перевод статьи Пьера-Хьюза Шарбонне)

Как уже сообщалось ранее на Java One, в Java 8 планируется отказаться от PermGen пространства в пользу новой его вариации — Metaspace. Ранний доступ к JDK 8 даёт возможность наблюдать Metaspace в действии, чем и воспользовался автор оригинальной статьи чтоб узнать, какие преимущества даёт MetaSpace в сравнении с PermGen, и убедится во всём непосредственно.

Подробнорсти под катом.

Что такое Metaspace

В рамках мерджа HotSpot с JRockit хранение метаданных о классах будет осуществляться в нативной памяти, по аналогии с JRockit и IBM JVM. Часть нативной памяти, отведённая под эти метаданные, носит название Metaspace.

Итак, Metaspace это замена PermGen, основное отличие которой с точки зрения Java-программистов — возможность динамически расширятся, органиченная по умолчанию только размером нативной памяти. Параметры PermSize и MaxPermSize отныне упразднены (получив эти параметры JVM будет выдавать предупреждение о том, что они более не действуют), и вместо них вводится опциональный параметр MaxMetaspaceSize, посредством которого можно задать ограничение на размер Metaspace.

В результате максимальный Metaspace по умолчанию не ограничен ничем кроме предела объёма нативной памяти. Но его можно по желанию ограничить параметром MaxMetaspaceSize, аналогичным по сути к MaxPermSize.

Предполагается, что таким образом можно будет избежать ошибки «java.lang.OutOfMemoryError: PermGen space» за счёт большей гибкости динамического изменения размера Metaspace. Но, конечно, если размер Metaspace достигнет своей границы — будь то максимум объёма нативной памяти, или лимит заданный в MaxPermSize — будет выброшено аналогичное исключение: «java.lang.OutOfMemoryError: Metadata space».

Сборка мусора

Логи Garbage Collector-а будут сообщать также и о сборке мусора в Metaspace.

Сама сборка мусора, если верить автору статьи, будет происходить при достижении Metaspace размера, заданного в MaxMetaspaceSize. Но его же эксперименты (см. ниже) показывают, что когда MaxMetaspaceSize не задан, сборка мусора в Metaspace тоже осуществляется перед каждым его динамическим увеличением.

Эксперименты

Автор статьи провёл три эксперимента по заполнению PermGen Space / Metaspace (все на 64-bit весиях JVM):

  • JDK 1.7, MaxPermSize = 128 MB
  • JDK 1.8 (b75), MaxMetaspaceSize не задан
  • JDK 1.8 (b75), MaxMetaspaceSize = 128 MB

В результате автор обнаружил, что:

  • при MaxPermSize = 128 MB на JDK 1.7 ему удалось загрузить чуть более 30 тысяч классов до выбрасывания исключения «OutOfMemoryError: PermGen space».
  • при отсутствии лимита MaxMetaspaceSize на JDK 1.8 его программа загрузила 50 тысяч классов (больше он не пробовал) без получения исключений
  • при лимите MaxMetaspaceSize в 128 MB на JDK 1.8 результат был аналогичен MaxPermSize = 128 MB на JDK 1.7 — удалось загрузить чуть более 30 тысяч классов до выбрасывания исключения «OutOfMemoryError: Metadata space»

В оригинальной статье автор также приводит графики использования памяти и логи Garbage Collector-а — для тех кому это интересно. Графики и логи должны быть понятны без перевода.

От себя добавлю, что такое нововведение может быть полезно для запуска java кода на клиентских машинах. Например ant/maven билд скриптов, которым ранее иногда приходилось поднимать MaxPermSize для успешного завершения билда. А также будет весьма полезно в тех (пусть и редких) случаях, когда используются десктопные Java приложения, оганичение PermGen для которых никогда не имело особого смысла.

Автор: Sauron

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js