openjdk.ruOpenJDK на русском

JEP 122: Remove the Permanent Generation

Удаление permanent generation

ОтветственныйJon Masamitsu
ТипFeature
ОбластьImplementation
СтатусClosed / Delivered
Выпуск8
Компонентhotspot / gc
Обсуждениеhostspot dash dev at openjdk dot java dot net
ТрудоёмкостьXL
ДлительностьXL
БлокируетJEP 156: G1 GC: Reduce need for full GCs
РецензентыPaul Hohensee
ОдобренPaul Hohensee
Создан2010/08/15 20:00
Обновлён2014/08/06 14:14
Задача8046112

Аннотация

Удалить permanent generation из HotSpot JVM и тем самым избавиться от необходимости настраивать размер permanent generation.

Что не является целью

Распространение Class Data Sharing на классы приложения. Сокращение объёма памяти, необходимого для метаданных классов. Возможность асинхронной сборки метаданных классов.

Критерии успеха

Метаданные классов, интернированные строки и статические переменные классов будут перенесены из permanent generation либо в кучу Java, либо в нативную память.

Код permanent generation в HotSpot JVM будет удалён.

Время запуска приложений и потребление памяти ухудшатся не более чем на 1 % по результатам измерений на наборе бенчмарков, который ещё предстоит выбрать.

Мотивация

Это часть работы по объединению JRockit и HotSpot. Клиентам JRockit не нужно настраивать permanent generation (поскольку в JRockit нет permanent generation), и они привыкли не настраивать permanent generation.

Описание

Перенести часть содержимого permanent generation в HotSpot в кучу Java, а остальное — в нативную память.

Представление классов Java в HotSpot, которое здесь называется метаданными классов, сейчас хранится в части кучи Java, которая называется permanent generation. Кроме того, в permanent generation хранятся интернированные строки и статические переменные классов. Областью permanent generation управляет HotSpot, и в ней должно хватать места для всех метаданных классов, интернированных строк и статических переменных классов, которые использует приложение Java. Метаданные и статические переменные класса размещаются в permanent generation при загрузке класса и удаляются из permanent generation сборщиком мусора при выгрузке класса. Интернированные строки также удаляются сборщиком мусора при сборке мусора в permanent generation.

Предлагаемая реализация будет размещать метаданные классов в нативной памяти, а интернированные строки и статические переменные классов перенесёт в кучу Java. HotSpot будет явно выделять и освобождать нативную память для метаданных классов. Выделение памяти под новые метаданные классов будет ограничено объёмом доступной нативной памяти, а не фиксированным значением -XX:MaxPermSize, будь то значение по умолчанию или заданное в командной строке.

Нативная память для метаданных классов будет выделяться блоками такого размера, чтобы в них помещалось несколько фрагментов метаданных классов. Каждый блок будет связан с загрузчиком классов, и все метаданные классов, загруженные этим загрузчиком, HotSpot будет размещать в блоке этого загрузчика. Дополнительные блоки будут выделяться загрузчику классов по мере необходимости. Размеры блоков будут меняться в зависимости от поведения приложения. Размеры будут выбираться так, чтобы ограничить внутреннюю и внешнюю фрагментацию. Место, занятое метаданными классов, будет освобождаться, когда загрузчик классов перестанет существовать, путём освобождения всех блоков, связанных с этим загрузчиком. Метаданные класса не будут перемещаться в течение жизни класса.

Альтернативы

Цели избавиться от необходимости задавать размер permanent generation можно достичь, сделав permanent generation расширяемой. Существуют дополнительные структуры данных, которые пришлось бы расширять вместе с permanent generation (например, card table и block offset table). Для эффективной реализации permanent generation должна была бы выглядеть как одна непрерывная область, часть которой непригодна для использования.

Тестирование

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

Риски и допущения

Основной риск — объём изменений в HotSpot JVM. Кроме того, что именно нужно изменить, скорее всего, удастся точно определить только в ходе реализации.

Это большой проект, который существенно затрагивает все сборщики мусора. Знание о permanent generation и о том, как она работает, заложено как в среде выполнения, так и в компиляторе HotSpot JVM. Структуры данных за пределами сборщиков мусора будут изменены, чтобы упростить сборщику мусора обработку метаданных классов в нативной памяти.

Некоторые части JVM, скорее всего, придётся реализовать заново в рамках этого проекта. Например, будет затронут механизм Class Data Sharing, и может потребоваться его полная или частичная повторная реализация.

Переопределение классов — область риска. Переопределение опирается на сборку мусора метаданных классов во время сборки permanent generation (т. е. сейчас переопределение не освобождает переопределённые классы, поэтому понадобится какой-то способ определять, когда можно освободить метаданные переопределённых классов).

Перенос интернированных строк и статических переменных классов в кучу Java может привести к исключению Out-of-memory или к увеличению числа сборок мусора. Пользователю может потребоваться скорректировать значение -Xmx.

При включённом параметре UseCompressedOops указатели на метаданные классов (в permanent generation) могут сжиматься так же, как указатели на кучу Java. Это даёт значительный прирост производительности (порядка нескольких процентов). Указатели на метаданные в нативной памяти будут сжиматься похожим образом, но с другой реализацией. Эта последняя реализация может оказаться не такой производительной, как сжатие указателей на кучу Java. Требования к сжатию указателей на метаданные могут ограничить максимальный размер метаданных. Например, если реализация потребует размещать все метаданные ниже некоторого адреса (например, ниже границы 4g), это ограничит размер метаданных.

Зависимости

Инструменты, которые знают о permanent generation, придётся реализовать заново. Serviceability agent, jconsole, Java VisualVM и jhat — примеры инструментов, которые будут затронуты.

Влияние

  • Другие компоненты JDK: инструменты, которые знают о permanent generation.

  • Совместимость: флаги командной строки, относящиеся к permanent generation, станут устаревшими.

  • Документация: упоминания permanent generation необходимо будет удалить.