В чем разница между young generation и old generation в сборке мусора и зачем их два
Что проверяют
Знаете ли вы, на какой идее построена поколенческая сборка и во что она обходится. Обычно следом просят объяснить, как объект попадает в старое поколение и что такое premature promotion.
Как отвечать
Начните с гипотезы, на которой всё держится: большинство объектов умирает молодыми (итераторы, DTO запроса, временные строки). Если собирать их отдельно и часто, основная работа приходится на маленькую область, где почти всё уже мусор.
- young generation: Eden и два survivor-пространства. Новые объекты создаются в Eden. При minor GC живые объекты копируются в свободный survivor, а Eden очищается целиком. Стоимость копирующей сборки пропорциональна числу живых объектов, а не мусора, поэтому она быстрая;
- возраст объекта: каждая пережитая сборка увеличивает счётчик. Когда он доходит до порога (верхнюю границу задаёт
-XX:MaxTenuringThreshold, максимум 15), объект переезжает в old. JVM может снижать порог сама, а при переполнении survivor объекты уезжают раньше; - old generation: долгоживущие данные, кеши, пулы. Собирается реже и другими алгоритмами: пометка и уплотнение, а в G1 смешанные сборки, где вместе с young чистится часть старых регионов.
Зачем разделять: разным популяциям подходят разные алгоритмы. Копирование хорошо там, где выживает мало, и плохо для гигабайтов долгоживущих данных.
У разделения есть цена: ссылки из old в young. Чтобы minor GC не сканировал весь old, JVM ведёт card table (в G1 ещё remembered sets) и платит за это write barrier на каждой записи ссылки.
Упомяните современное состояние: G1 работает по умолчанию с Java 9 и сам подбирает размер young под -XX:MaxGCPauseMillis, а у ZGC с JDK 21 появился поколенческий режим, который позже стал единственным.
Где спотыкаются
Говорят, что minor GC не останавливает приложение. В G1 и Parallel это пауза stop-the-world, просто короткая.
Утверждают, что объект уходит в old ровно после 15 сборок. Порог динамический, а большие объекты в G1 (humongous) сразу попадают в старые регионы.
Жёстко задают -Xmn при G1 «для скорости». Так вы отключаете адаптивный подбор young под цель по паузам.