JEP 344: Abortable Mixed Collections for G1
Прерываемые смешанные сборки мусора в G1
| Ответственный | Erik Helin |
| Тип | Feature |
| Область | Implementation |
| Статус | Closed / Delivered |
| Выпуск | 12 |
| Компонент | hotspot / gc |
| Обсуждение | hotspot dash gc dash dev at openjdk dot java dot net |
| Трудоёмкость | M |
| Длительность | M |
| Рецензенты | Mikael Vidstedt, Stefan Johansson, Thomas Schatzl |
| Одобрен | Mikael Vidstedt |
| Создан | 2017/10/27 09:56 |
| Обновлён | 2019/07/15 10:04 |
| Задача | 8190269 |
Аннотация
Сделать смешанные сборки в G1 прерываемыми, если они могут превысить целевое время паузы.
Что не является целью
Сделать прерываемыми все паузы в G1.
Мотивация
Одна из целей G1 — укладываться в заданное пользователем целевое время пауз сборки мусора. G1 использует развитый механизм анализа, чтобы выбрать объём работы, выполняемой за одну сборку (отчасти этот выбор основан на поведении приложения). Результат этого выбора — набор регионов, называемый collection set. После того как collection set определён и сборка начата, G1 должен собрать все живые объекты во всех регионах collection set без остановки. Из-за этого G1 может превысить целевое время паузы, если эвристики выберут слишком большой collection set; так бывает, например, когда поведение приложения меняется и эвристики работают на «устаревших» данных. Особенно это заметно при смешанных сборках, где collection set часто может содержать слишком много старых регионов. Нужен механизм, который обнаруживает, что эвристики раз за разом выбирают неверный объём работы для сборок, и в таком случае заставляет G1 выполнять сборку инкрементально, по шагам, так что после каждого шага сборку можно прервать. Такой механизм позволил бы G1 чаще укладываться в целевое время паузы.
Описание
Если G1 обнаруживает, что эвристики выбора collection set раз за разом выбирают неверное число регионов, он переходит к более инкрементальному способу выполнения смешанных сборок: collection set делится на две части — обязательную и необязательную. Обязательная часть включает те части collection set, которые G1 не может обрабатывать инкрементально (например, молодые регионы), но для большей эффективности может содержать и старые регионы. Например, это может быть 80 % прогнозируемого collection set. Оставшиеся 20 % прогнозируемого collection set, состоящие только из старых регионов, образуют необязательную часть.
Закончив сборку обязательной части, G1 начинает собирать необязательную часть с гораздо более мелкой гранулярностью, если осталось время. Гранулярность сборки необязательной части зависит от оставшегося времени, вплоть до 1 региона за раз. Завершив сборку любой части необязательного collection set, G1 может решить остановить сборку в зависимости от оставшегося времени.
Когда прогнозы снова становятся точнее, необязательная часть сборки становится всё меньше, пока обязательная часть снова не охватит весь collection set (то есть G1 полностью полагается на свои эвристики). Если прогнозы опять становятся неточными, следующие сборки снова будут состоять из обязательной и необязательной частей.
Альтернативы
-
Улучшить механизм анализа и эвристики, чтобы они не давали плохих прогнозов. Хотя это интересная цель сама по себе, эвристики зависят от прошлого поведения приложения, поэтому добиться 100 % точности эвристик невозможно. Тем не менее улучшенные эвристики автоматически уменьшат потребность в этом механизме.
-
Всегда использовать «запас прочности» относительно прогноза. Например, если прогноз возвращает x, всегда использовать 0,8 * x (запас 20 %). Вероятно, в большинстве случаев это сработает, но приведёт к неоптимальной производительности, когда прогнозы верны, поскольку тогда G1 будет использовать лишь 80 % целевого времени паузы.
-
Использовать для прерывания смешанных сборок существующий механизм обработки evacuation failure. Эта альтернатива отклонена, поскольку в момент такого прерывания нет гарантии, что сборка освободила хотя бы один регион. Предлагаемый нами механизм гарантирует продвижение в освобождении памяти, освобождая пространство collection set по регионам, а регион — это единица гранулярности освобождения памяти в G1.
Тестирование
Отдельные части реализации на C++ следует тестировать модульными тестами на C++. Поскольку код прерываемых смешанных сборок станет неотъемлемой частью G1 GC, он будет задействован уже при запуске существующих тестов.
Риски и допущения
-
При делении collection set на обязательную и необязательную части для необязательной части collection set нужно поддерживать некоторые дополнительные данные. Это даёт небольшие накладные расходы на CPU — менее 1 % и только для смешанных сборок, использующих необязательную часть collection set.
-
Использование нативной памяти во время смешанных сборок с необязательной частью collection set также может вырасти. Это связано с тем, что во время такой смешанной сборки необходимо отслеживать некоторые дополнительные входящие указатели на регионы необязательной части.