В Java виртуальная машина (JVM) управляет несколькими областями памяти:
- Heap (Куча): Общая область для всех потоков приложения. Здесь хранятся объекты и массивы. Размер кучи определяется настройками JVM. Именно в куче работает сборщик мусора.
- Stack (Стек): Область памяти для каждого потока. Хранит локальные переменные примитивных типов и ссылки на объекты в куче. Размер стека фиксированный или динамически изменяемый в зависимости от настроек JVM.
- Method Area (Область методов): Хранит структуры per-class (runtime constants pool, field and method data, the code for methods and constructors). В более новых версиях Java объединена с Metaspace.
- Metaspace: Непотоконезависимая область памяти, хранит метаданные классов. Размер по умолчанию не ограничен (зависит от доступной памяти).
- PC Register (Program Counter Register): Указатель на инструкцию JVM, которая выполняется в данный момент. Есть у каждого потока.
- Native Method Stack (Указатель на нативный метод стека): Для поддержки вызовов нативных (не Java) методов.
Сборщик мусора (Garbage Collector, GC) - автоматический процесс управления памятью в куче. Он освобождает память, занятую объектами, на которые нет ссылок. Это предотвращает утечки памяти.
Основные этапы работы GC:
- Marking (Пометка): GC определяет, какие объекты доступны (reachable) из корневых элементов (например, ссылки из стеков потоков, статические переменные). Остальные объекты считаются недоступными (unreachable).
- Sweeping (Очистка): GC освобождает память, занятую недоступными объектами.
- Compacting (Компактизация): Некоторые сборщики мусора перемещают доступные объекты, чтобы устранить фрагментацию памяти.
Принцип работы GC основан на концепции поколений (Generational Garbage Collection):
- Young Generation (Молодое поколение): Область для новых объектов. Большинство объектов умирают быстро, поэтому GC здесь работает часто и быстро.
- Eden Space: Область, куда создаются новые объекты.
- Survivor Spaces (S0, S1): Объекты, пережившие сборку мусора в Eden, перемещаются сюда. Объекты перемещаются между S0 и S1 при каждой сборке.
- Old Generation (Старое поколение): Область для объектов, которые пережили несколько сборок в молодом поколении (прошли определенный "возраст"). GC здесь работает реже, но дольше.
- Permanent Generation (PermGen): В более старых версиях Java, хранила метаданные классов и статические данные. Заменена Metaspace.
Различные реализации GC (G1, CMS, Serial, Parallel, ZGC, Shenandoah) используют разные алгоритмы для пометки, очистки и компактизации, оптимизированные для разных сценариев.