Прочитал недавно несколько статей про CMS и G1, очень обидно.Многие статьи вы копируете мне, а я ему, и везде копия неправильная. Или просто бросить туда несколько грубых концепций, что на самом деле является пустой тратой времени людей, ищущих информацию.
Потратил день на просмотрRednaxelaFX
Пост вопросов и ответов от Great God и другие материалы разобрали некоторые детали реализации CMS и G1. Здесь не будут повторяться основные понятия и многое из того, что искали поисковые системы. Нет порядка, в котором нужно писать то, о чем вы думаете.
Что такое корень gc на начальной стадии разметки CMS?
В контексте начальной отметки CMS корневой набор не включает в себя молодое поколение, а только стек, регистр и глобальные переменные. Это связано с тем, что на следующем этапе параллельной маркировки CMS CMS будет проходить все живые объекты в молодом поколении по начальному корневому набору. Таким образом, с точки зрения комбинации начальной метки CMS + параллельной метки, молодой ген все еще является частью корневого набора (поскольку он сканируется, но не собирается).
То есть набор корней gc фактической начальной стадии маркировки не включает новое поколение и будет пройден на параллельной стадии маркировки (точнее, на стадии предварительной очистки). Однако в фазе ремарки новое поколение будет пройдено снова.Причина та же, что и грязная карта старого поколения.Новое поколение также будет иметь такую динамическую грязную карту во время выполнения.
Значок региона G1
Выдержка из блога Meituan Technology https://tech.meituan.com/2016/09/23/g1.html
H указывает на то, что эти Регионы хранят огромные объекты (humongous objects, H-obj), то есть объекты, размер которых больше или равен половине региона.H-obj напрямую отнесены к старому поколению, предотвращая повторное копирование и перемещение .
При каких обстоятельствах будут происходить пропуски?
В CMS и G1 мы используем черный, белый и серый цвета для обозначения сканируемых объектов:
-
Белый: объект не был помечен.После завершения фазы пометки он будет собран как мусор.
-
Серый: объект помечен, но его поля не помечены и не заполнены.
-
Черный: объект отмечен, и все его поля отмечены.
Для возникновения упущения должны одновременно выполняться следующие два условия:
1. Приложение вставляет новую ссылку из черного объекта в белый объект
2. Приложение удаляет все прямые или косвенные ссылки с серого объекта на белый объект.
Вставка новой ссылки на черно-белый объект означает, что белый объект, который изначально должен был быть удален сборщиком мусора, имеет новую ссылку и становится доступным, а поскольку это ссылка, сгенерированная черным объектом, черный объект не будет быть повторно отсканированы для расчета. Таким образом, белый объект будет пропущен, но если на белый объект все еще ссылается серый объект, его можно спасти, потому что серый объект не был отмечен, а затем серый объект будет отсканирован до белый объект.
Используйте грязную карту, чтобы решить проблему с пропущенными ставками
JVM делит память на блоки фиксированного размера.card
, а затем иметь выделенную структуру данных (т.е. здесьCard Table
) поддерживать каждыйCard
состояние, один байт соответствует одномуCard
. когдаCard
Когда ссылка на объект наCard
соответствующийCard Table
Статус установлен на dirty (фактически используется таблица mod-union). Затем эти грязные карты обрабатываются на этапах предварительной очистки и примечания.
В чем разница между CMS и грязной картой с пометкой G1?
- CMS используетincremental updateБарьер записи, также известный как барьер вставки, связан со вставкой новых ссылочных отношений.
- G1 используетSATBБарьер записи (Snapshot-At-The-Beginning) также называется барьером удаления, который связан с удалением старых эталонных отношений.
Метод инкрементного обновления заключается в следующем: пока ссылка на белый объект оказывается назначенной на поле черного объекта в барьере записи, белый объект превращается в серый (например, помечая и нажимая на него на стек маркировки, или записанный в аналогичной таблице мод-объединений). Это сильно предотвращает возникновение первой ситуации.
Подход SATB заключается в том, чтобы рассматривать все живые объекты в логическом снимке в начале маркировки как живые. Конкретный метод заключается в том, чтобы все объекты, на которые указывают старые ссылки, стали небелыми в барьере записи (если он уже черно-серый, вам не нужно об этом беспокоиться, а если он белый, он станет серый). Фактический эффект от этого таков: если поле серого объекта изначально указывает на белый объект, но до того, как параллельный маркер сможет просканировать это поле, этому полю присваивается другое значение (например, null), то это поле не является белым Связь между объектами разорвана. Барьер записи SATB гарантирует, что объект, на который изначально ссылается поле, будет выделен серым цветом до того, как произойдет отсечка, тем самым предотвращая вторую описанную выше ситуацию.
Плавающий мусор для CMS и G1
CMS заботится только о вставках новых ссылочных отношений, а не об их удалении. Поэтому при удалении ссылки на черный объект CMS не воспримет его, а также удалит помеченный объект, в результате чего мусорный объект не будет удален в этом раунде.
G1 фокусируется только на удалении и обрабатывает все новые объекты после первоначальной маркировки как черные объекты (исходные объекты, просто добавленные ссылки, не будут генерировать плавающий мусор), и станут ли эти объекты мусором во время параллельной маркировки G1 не касается. Таким образом, G1 может генерировать больше плавающего мусора в одном сборщике мусора, чем CMS.
CMS Precleaning (предварительная очистка) и AbortablePreclean (предварительная очистка может быть прервана)
Следует иметь в виду, что две фазы предварительной очистки и прерываемой предварительной очистки не являются обязательными и могут быть отключены с помощью параметра XX:-CMSPrecleaningEnabled. Предпосылка выполнения цикла AbortablePreclean заключается в том, что использование памяти области Eden больше, чем CMSScheduleRemarkEdenSizeThreshold (по умолчанию 2 М). Если в новом поколении слишком мало объектов, нет необходимости выполнять этот этап, и этап перемаркировки выполняется напрямую. Фаза предварительной очистки в основном выполняет две задачи: 1. Сканирует молодое поколение для обработки динамически сгенерированных новых ссылок на старое поколение. 2. Обрабатывает ранее отмеченные грязные карты. Прерываемая предварительная очистка, как и предварительная очистка, выполняется только в цикле и имеет следующие условия прерывания:
-
Количество циклов превышает максимальное количество циклов CMSMaxAbortablePrecleanLoops, значение по умолчанию равно 0, что означает отсутствие ограничений на количество циклов.
-
Время выполнения цикла достигает порогового значения CMSMaxAbortablePrecleanTime, которое по умолчанию равно 5 с.
-
Использование памяти в области Eden нового поколения достигло порога CMSScheduleRemarkEdenPenetration (по умолчанию 50%).
Стадия предварительной очистки выполняется параллельно, цель состоит в том, чтобы уменьшить давление стадии ремарки. Циклическая предварительная очистка ожидает Young GC в течение 5 секунд, что значительно снижает стоимость сканирования молодого поколения на этапе замечаний. Однако мы также можем указать GC, который должен быть выполнен перед AbortablePreclean, с помощью параметра CMSScavengeBeforeRemark.
В Meituan Dianping есть статья об оптимизации CMS, в которой этот параметр используется для того, чтобы заставить AbortablePreclean выйти из цикла раньше времени. Я чувствую, что есть проблема с выражением. Должно быть, при включении этого параметра использование области Эдема меньше CMSScheduleRemarkEdenSizeThreshold, что приводит к пропуску этапа AbortablePreclean.
CSet и RSet G1
Набор коллекций (CSet)
CSet записывает коллекцию регионов, которые должны быть собраны GC, и регионы в коллекции могут быть любого возраста. Ссылки вне CSet в GC можно игнорировать.На этот раз каждый GC заботится только о регионах в CSet.
remembered set
По логике, у каждого Региона есть RSet.RSet записывает отношения между объектами в других Регионах и объектами в этом Регионе.Он принадлежит структуре point-in (кто ссылается на мой объект).RSet реализован на основе карточной таблицы. Например, объект A ссылается на объект B, то есть A.filed=B. Затем RSet B запишетКарта, на которой находится объект Аадрес г.
Изображение взято из блога Meituan Technology https://tech.meituan.com/2016/09/23/g1.html.
Что разделяют фаза G1 начальной оценки и Young gc?
Начальная маркировка глобальной параллельной маркировки разделяет фазу паузы с молодым сборщиком мусора и фактически разделяет корневой набор из сканирования молодого сборщика мусора. Молодой gc может делать начальную маркировку случайно или нет.
Почему G1 не заботится об обновлении отношения ссылки на объект Young gen?
Есть два подрежима выбранного CSet в режиме поколения G1, соответствующие молодому GC и смешанному GC:
-
Young GC: выберите все регионы в молодом поколении. Накладные расходы молодого GC контролируются путем контроля количества регионов молодого поколения.
-
Смешанный GC: выберите все регионы молодого поколения, а также несколько регионов старого поколения с высоким доходом от сбора в соответствии с глобальной статистикой одновременной маркировки. Выберите наиболее прибыльный регион старого поколения в пределах диапазона целевых затрат, указанного пользователем.
можно увидетьрегион молодого поколения всегда находится внутри CSet. G1 gc связан со ссылкой вне Cset на Cset, поэтому G1 поколения не поддерживает обновление RSet, связанное со ссылкой из области молодого поколения. И CMS перерабатывает только старое поколение, поэтому «CSet» CMS - это старое поколение, конечно, вас должно беспокоить изменение эталона молодого поколения.
Процесс эвакуации G1
Процесс эвакуации — это процесс очистки. Этот процесс и глобальная параллельная маркировка — два относительно независимых процесса. Фаза эвакуации полностью приостановлена. Он отвечает за копирование живых объектов в части региона в пустой регион, а затем за освобождение пространства исходного региона. В процессе эвакуации можно выбрать любое количество Cset для переработки, потому что у каждого региона есть соответствующий Rset, и эти объекты можно считать живыми с помощью Rset.
Каковы преимущества G1 перед CMS?
- Хотя G1 помечает всю кучу, он не эвакуирует все регионы с живыми объектами; выбирая для эвакуации только небольшое количество регионов с высокой доходностью, можно контролировать накладные расходы на эту паузу (в пределах определенного диапазона). Но ведь для копирования объектов необходимо делать паузу, и время этой паузы ограничено, каким бы малым оно ни было. Эвакуационная пауза G1 в норме составляет от десятков до ста и даже двухсот миллисекунд. Так что помните, не устанавливайте -XX:MaxGCPauseMillis слишком низким, иначе G1 не сможет идти в ногу с целью, и это легко приведет к накоплению мусора, но с большей вероятностью вызовет полный GC и снизит производительность. Обычно устанавливается на 100 мс, 250 мс и т.п. может быть разумным.
- Комментарий CMS должен повторно сканировать грязную карту в таблице модов-объединений плюс весь корневой набор.В это время весь молодой ген (независимо от того, мертв объект или жив) будет рассматриваться как часть корневого набора, поэтому замечание CMS может быть очень медленным. Если во время параллельной фазы маркировки CMS мутатор все еще выделяет память с высокой скоростью, так что в молодом поколении много объектов, фаза маркировки может иметь длительную паузу. Чем больше молодое поколение, тем дольше может быть время паузы для комментариев CMS. И на заключительном этапе маркировки (или перемаркировки) G1 нужно только сканировать буфер SATB.
- CMS использует метод очистки для повторного использования, что приведет к фрагментации памяти. Фаза эвакуации G1d использует алгоритм репликации, и фрагментации не будет.