Глубокое понимание памяти JVM

Содержание

Куча

Во время выполнения Java-программ Java Virtual Machine (JVM) делит управляемую память в основной памяти на несколько областей, каждая из которых хранит разные типы данных. Наибольшая часть памяти называется кучей (Heap), которая является областью данных во время выполнения Java Virtual Machine, где хранятся все экземпляры и массивы.

Куча создается при запуске Java Virtual Machine, ею делятся все потоки, и это также основная рабочая область для сборщика мусора, поэтому эта часть области также называется Память кучи или Куча GC. Когда сборщик мусора перерабатывает данные в куче, он сканирует и очищает бесполезные объекты, созданные с помощью ключевого слова new, освобождая память и избегая расточительства ресурсов памяти.

Для улучшения эффективности сборки мусора память кучи дополнительно делится на Молодое поколение, Старое поколение и Постоянное поколение.

JVM Heap

  • Молодое поколение: Включает область Эдена, область SurvivorFrom и область SurvivorTo, используется для хранения вновь созданных объектов. Большинство новых объектов выделяются в области Эдена (если объект слишком большой, он напрямую выделяется в Старом поколении), а процесс сборки мусора в Молодом поколении называется Малой сборкой мусора. Когда памяти в области Эдена недостаточно, срабатывает Малая сборка мусора.

    Перед началом Малой сборки мусора объекты существуют только в области Эдена и области SurvivorFrom; во время Малой сборки мусора выжившие объекты из области Эдена и области SurvivorFrom перемещаются в область SurvivorTo, и их возраст увеличивается на 1, в то время как область Эдена и область SurvivorFrom очищаются; после Малой сборки мусора функции области SurvivorFrom и области SurvivorTo меняются местами, и во время следующей Малой сборки мусора выжившие объекты из области SurvivorTo и области Эдена перемещаются в область SurvivorFrom, и возраст объектов пересчитывается. Когда возраст объекта достигает 15, он выделяется в Старое поколение.

  • Старое поколение: Также известное как область Вечности, используется для хранения объектов, переживших Молодое поколение. Процесс сборки мусора из области Старого поколения называется Большой сборкой мусора. Старое поколение хранит более стабильные объекты и не подвергается Большой сборке мусора слишком часто. Большая сборка мусора срабатывает только тогда, когда новые объекты попадают в Старое поколение, вызывая недостаток пространства, или когда программа не может найти достаточно большой непрерывный участок для выделения новым большим объектам.

    Поскольку требуется сканирование и переработка, Большая сборка мусора занимает больше времени. Большая сборка мусора приводит к фрагментации памяти, и когда в Старом поколении также недостаточно памяти для выделения входящим объектам, возникает исключение OOM (Out of Memory).

  • Постоянное поколение: Также известное как область постоянного хранения, в основном хранит информацию о классах и метаданные. В Java 8 Постоянное поколение было удалено и заменено областью Metaspace. Metaspace не находится в виртуальной машине, а использует локальную память. Поэтому по умолчанию размер Metaspace ограничен только локальной памятью.

Непосредственная память

Непосредственная память относится к области памяти, управляемой вне кучи Java Virtual Machine, выделяющей некоторые экземпляры объектов в областях памяти вне кучи Java Virtual Machine, которые напрямую управляются операционной системой (а не виртуальной машиной), включая область кэширования кода, Metaspace/Постоянное пространство.

Объяснения областей представлены в таблице ниже.

Область Непосредственной ПамятиОписание
Кэш кодаОбласть для компиляции и хранения нативного кода.
Постоянное пространствоОбласть для хранения статических данных виртуальной машины, таких как объекты классов и методов.
МетапамятьMetaspace, область для хранения метаданных классов в локализованной памяти.
Прямой буферОбласть прямого буфера.