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

Содержание

Heap Memory

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

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

Для повышения эффективности сборки мусора heap memory дополнительно делится на Young Generation, Old Generation и Permanent Generation.

JVM Heap

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

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

  • Old Generation: Также известна как Tenured area, используется для хранения объектов, переживших Young Generation. Процесс сборки мусора в Old Generation называется Major GC. Old Generation хранит более стабильные объекты и не выполняет Major GC часто. Major GC запускается только когда новые объекты попадают в Old Generation и вызывают нехватку места, либо когда программа не может найти достаточно большой непрерывный участок памяти для выделения новым большим объектам.

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

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

Non-Heap Memory

Non-Heap Memory — это область памяти, управляемая вне heap Java Virtual Machine, выделяющая некоторые экземпляры объектов в областях памяти вне heap JVM, которые напрямую управляются операционной системой (а не виртуальной машиной), включая область Code Cache и Metaspace/Permanent Space.

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

Область Non-Heap MemoryОписание
Code CacheОбласть для компиляции и хранения нативного кода.
Permanent SpaceОбласть для хранения статических данных виртуальной машины, таких как объекты классов и методов.
Meta SpaceMetaspace — область для хранения метаданных классов в локализованной памяти.
Direct BufferОбласть прямого буфера.