Во время выполнения 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.
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 — это область памяти, управляемая вне heap Java Virtual Machine, выделяющая некоторые экземпляры объектов в областях памяти вне heap JVM, которые напрямую управляются операционной системой (а не виртуальной машиной), включая область Code Cache и Metaspace/Permanent Space.
Описание областей приведено в таблице ниже.
Область Non-Heap Memory | Описание |
---|---|
Code Cache | Область для компиляции и хранения нативного кода. |
Permanent Space | Область для хранения статических данных виртуальной машины, таких как объекты классов и методов. |
Meta Space | Metaspace — область для хранения метаданных классов в локализованной памяти. |
Direct Buffer | Область прямого буфера. |