middle
Какие сборщики мусора существуют в JVM
Сборщик мусора (Garbage Collector, GC) — это компонент JVM, автоматически освобождающий память, занятую объектами, на которые больше нет ссылок. JVM предоставляет несколько реализаций GC, каждый из которых оптимизирован для конкретных сценариев.
| Сборщик | Флаг | Описание | Когда использовать |
|---|---|---|---|
| Serial GC | -XX:+UseSerialGC |
Однопоточный, stop-the-world | Маленькие приложения, <100 MB heap, embedded |
| Parallel GC | -XX:+UseParallelGC |
Многопоточный, stop-the-world | Пакетная обработка, важна пропускная способность |
| CMS | -XX:+UseConcMarkSweepGC |
Concurrent Mark-Sweep, фоновая сборка | Deprecated (Java 9), удалён (Java 14) |
| G1 GC | -XX:+UseG1GC |
Region-based, баланс паузы/throughput | По умолчанию с Java 9, heap > 4 GB |
| ZGC | -XX:+UseZGC |
Сверхнизкие паузы (<1 мс), concurrent compaction | Большие heap (до 16 TB), low-latency |
| Shenandoah | -XX:+UseShenandoahGC |
Сверхнизкие паузы, concurrent compaction | Аналогично ZGC, доступен в OpenJDK |
| Epsilon GC | -XX:+UseEpsilonGC |
Не собирает мусор (no-op) | Тестирование, короткоживущие процессы |
Эволюция GC в Java
- Java 8: по умолчанию Parallel GC
- Java 9: по умолчанию G1 GC; CMS помечен как deprecated
- Java 11: ZGC (экспериментальный); Epsilon GC
- Java 12: Shenandoah (экспериментальный, в OpenJDK)
- Java 14: CMS удалён
- Java 15: ZGC и Shenandoah стали production-ready
- Java 21: Generational ZGC (
-XX:+UseZGC -XX:+ZGenerational), по умолчанию с Java 23
Выбор сборщика мусора
Пример
Нужна максимальная пропускная способность?
-> Parallel GC
Нужны паузы < 200 мс при heap 4-32 GB?
-> G1 GC
Нужны паузы < 1 мс при любом размере heap?
-> ZGC или Shenandoah
Маленькое приложение (< 100 MB heap)?
-> Serial GC
Короткоживущий процесс (не нужна GC)?
-> Epsilon GC
Просмотр текущего GC
# Узнать, какой GC используется
java -XX:+PrintFlagsFinal -version 2>&1 | grep "Use.*GC "
# Логирование GC (Java 9+)
java -Xlog:gc*:file=gc.log:time,uptime,level,tags -jar app.jar
Частые ошибки
- Использование CMS-флагов на Java 14+ — JVM не запустится
- Выбор ZGC/Shenandoah для маленьких heap (< 256 MB) — overhead слишком большой
- Включение Parallel GC для low-latency систем — длинные stop-the-world паузы
- Игнорирование GC-логов в production — без них невозможно диагностировать проблемы с памятью
На собеседовании: назовите основные GC (Serial, Parallel, G1, ZGC, Shenandoah), укажите, какой используется по умолчанию (G1 с Java 9), и объясните, когда какой выбирать. Частая ловушка — вопрос про CMS: он удалён с Java 14. Покажите понимание компромисса между пропускной способностью (Parallel) и латентностью (ZGC/Shenandoah).