В какой области памяти JVM работает Garbage Collector?

«В какой области памяти JVM работает Garbage Collector?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Garbage Collector (GC) работает в области памяти, называемой Heap (куча). Куча разделена на поколения (Generations), что основано на гипотезе о слабом поколении (weak generational hypothesis).

Структура кучи и роль GC:

  1. Young Generation (Молодое поколение):

    • Eden (Эдем): Сюда помещаются все новые объекты при создании.
    • Survivor Spaces (S0 и S1, "To" и "From"): Сюда перемещаются объекты, пережившие сборку мусора в Eden.
    • Процесс: Когда Eden заполняется, запускается Minor GC. Живые объекты копируются в один из Survivor-пространств, а мёртвые удаляются. Объекты, пережившие несколько циклов Minor GC между S0 и S1, перемещаются в Old Generation.
  2. Old Generation (Tenured Generation, Старое поколение):

    • Здесь хранятся долгоживущие объекты.
    • Когда оно заполняется, запускается Major GC (или Full GC), который обычно работает дольше и может приостановить все потоки приложения (Stop-the-World).
  3. Metaspace (вместо PermGen, начиная с Java 8):

    • Хранит метаданные классов (структуры классов, методы, константный пул).
    • Важно: Сборка мусора здесь происходит, но она отделена от сбора в куче и вызывается при нехватке памяти Metaspace.

Визуализация и пример:

[ Heap Memory ]
|-----------------------|
|      Young Gen        | <-- Minor GC (быстрый)
|  [Eden][S0][S1]      |
|-----------------------|
|      Old Gen          | <-- Major/Full GC (медленный)
|-----------------------|
|      Metaspace        | <-- GC для метаданных классов
|-----------------------|
// Пример: объект становится кандидатом на сборку
public class GCDemo {
    public static void main(String[] args) {
        Object obj = new Object(); // Создается в Eden
        obj = null; // Прежний объект теперь недостижим
        // В какой-то момент GC удалит этот объект из памяти
        System.gc(); // Запрос к JVM, но не гарантия немедленного выполнения
    }
}

Итог: GC автоматически управляет памятью в куче, освобождая её от недостижимых объектов, используя разные алгоритмы для разных поколений (например, G1, ZGC, Shenandoah).