Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Этапы очистки мусора (Garbage Collection)
Garbage Collection (сборка мусора) — это автоматический процесс освобождения памяти от объектов, на которые больше нет ссылок. В Java существует несколько этапов этого процесса.
1. Mark фаза (Пометка)
Это первый и самый критичный этап. На этом этапе GC определяет, какие объекты находятся в живом состоянии:
- Сборщик мусора сканирует весь граф объектов, начиная с корневых ссылок (GC roots)
- К GC roots относятся:
- Локальные переменные в стеке потоков
- Статические переменные классов
- Объекты в очереди финализации
- Все объекты, достижимые из корней, помечаются как живые (live objects)
- Объекты, недостижимые из корней, считаются мёртвыми (garbage)
2. Sweep фаза (Удаление)
После того как все живые объекты помечены, происходит удаление мёртвых:
- GC проходит по всей памяти кучи (heap)
- Удаляет все объекты, не помеченные на этапе Mark
- Освобождает память, которую занимали эти объекты
- Память становится доступной для создания новых объектов
3. Compact фаза (Уплотнение)
Это опциональный этап, выполняемый после Sweep:
- После удаления мусора в памяти образуются фрагменты пустого места
- При длительной работе приложения это приводит к фрагментации памяти
- Compact перемещает все живые объекты в начало кучи, собирая их плотно
- Это улучшает производительность выделения памяти для новых объектов
- Также улучшает кэш-производительность процессора
Различные алгоритмы GC
В зависимости от сборщика мусора эти этапы могут выполняться по-разному:
// Serial GC - простой, однопоточный
// -XX:+UseSerialGC
// Mark -> Sweep -> Compact (последовательно)
// Parallel GC - многопоточный
// -XX:+UseParallelGC
// Mark, Sweep, Compact выполняются несколькими потоками
// CMS (Concurrent Mark Sweep) - параллельный
// -XX:+UseConcMarkSweepGC
// Mark и Sweep выполняются параллельно с приложением (но Compact нет)
// G1GC - современный, делит heap на регионы
// -XX:+UseG1GC
// Mark -> Sweep -> Compact (по регионам, более эффективно)
Стоп-мир (Stop-the-World)
Важный аспект: большинство этапов GC требуют, чтобы приложение было остановлено:
- Mark фаза часто требует STW для точности (хотя CMS и G1 частично параллельны)
- Compact фаза почти всегда требует STW
- Это время паузы приложения (GC pause time)
- Современные сборщики стремятся минимизировать паузы
Поколенческая гипотеза
Все современные JVM применяют оптимизацию на основе поколенческой гипотезы:
- Young Generation: новые объекты (быстрая сборка)
- Old Generation: долгоживущие объекты (редкая сборка)
- Minor GC: сборка Young (частая, короткая пауза)
- Major/Full GC: сборка Old (редкая, длинная пауза)
Это позволяет в большинстве случаев сборщику мусора работать только с молодым поколением, где большинство объектов умирают быстро.
Практический пример
public class GCExample {
public static void main(String[] args) {
// Создаём объекты в Young Generation
for (int i = 0; i < 1000000; i++) {
String str = new String("test");
// Объект помечается (Mark)
// Нет на него ссылок -> помечается как garbage
// Удаляется на этапе Sweep
}
// Создаём долгоживущий объект
List<String> longLived = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
longLived.add(new String("live"));
// Эти объекты пройдут в Old Generation
// Full GC будет нужен реже
}
}
}
Итого
Этапы GC (Mark-Sweep-Compact) — это фундамент управления памятью в Java. Понимание этих этапов необходимо для:
- Отладки проблем с памятью
- Оптимизации производительности приложения
- Выбора подходящего сборщика мусора
- Конфигурации heap size и GC параметров