В HotSpot VM к JDK 27 закрыли около 350 изменений в подсистеме GC. Примерно половина из них — рефакторинг: замена volatile и AtomicAccess-методов на явный Atomic<T> (JDK-8367013), чистка state machine в G1 и прочие улучшения кода. Ещё 35% — багфиксы и работа над надёжностью, а остальное — новые фичи и изменения поведения. Часть правок заложена в основу JEP 401 Value Objects (Preview): адаптировали object iterators и eager reclaim.
Главное событие — JEP 523: G1 теперь сборщик по умолчанию во всех окружениях. Раньше в некоторых случаях использовался Serial GC, теперь — нет. Если нужно, можно явно вернуть Serial через -XX:+UseSerialGC. Разработчики считают, что G1 лучше подходит как стартовая точка, хотя для некоторых приложений Serial может быть предпочтительнее.
G1 перестал менять размер кучи после Full GC по произвольным процентам -XX:MinHeapFreeRatio и -XX:MaxHeapFreeRatio. Их значения по умолчанию теперь 0% и 100% (было 40% и 70%). Старые дефолты заставляли эвристики конфликтовать: Full GC сжимал кучу, а другие эвристики почти сразу отменяли это изменение. Флаги оставили, но их работа теперь не мешает основным алгоритмам.
Адаптивный старт concurrent marking стал устойчивее к неблагоприятным условиям, из-за которых раньше возникала лишняя постоянная фоновая работа (JDK-8379846, JDK-8381006). Починили случай, когда humongous-объекты, которые реально можно было освободить, неожиданно удерживались слабыми ссылками (JDK-8378331, JDK-8378336). Ещё G1 Cleanup pauses больше не обновляют MemoryPoolMXBean.getCollectionUsage(), потому что эти паузы не меняют Java heap (JDK-8386332). А сборки, которым не хватило места для копирования, теперь учитываются в CPU-времени сборщика — это улучшает решения о размере кучи (JDK-8373894).
Parallel GC получил заметные фиксы. Адаптивный порог tenuring раньше мог только расти, из-за чего старые объекты занимали почти весь survivor space, и молодые преждевременно продвигались в старое поколение. Теперь порог может и снижаться (JDK-8380590). Ещё исправили ситуацию, когда куча не расширялась при большом числе Full GC из-за повторяющихся крупных аллокаций (JDK-8377561).
Serial GC особых изменений не получил, кроме того, что местами перестал быть дефолтным.
Общие правки для всех сборщиков: TLAB sizing стал лучше работать с приложениями, где много короткоживущих и слабо аллоцирующих потоков, — это уменьшает перерасход памяти и лишние сборки (JDK-8381834). Логирование string deduplication и JFR events улучшили: добавили «новые неизвестные» строки и более осмысленные агрегированные байты (JDK-8372348).
Дальше фокус остаётся на Automatic Heap Sizing — G1 должен ещё умнее реагировать на внешние условия и намерения пользователя.