Пусть люди, которых я встречу, вещи, которые я испытаю, даже если я стану немного лучше, я буду удовлетворен.
Сборщик мусора G1 (Garbage-First) — это новый сборщик мусора, официально используемый в JDK1.7. G1 имеет уникальную стратегию сборки мусора. С точки зрения поколений G1 по-прежнему является сборщиком мусора поколений. все еще области Эдема и выживших, но с точки зрения структуры кучи не требуется, чтобы вся область Эдема, династия Цин или старость были непрерывными. Он использует совершенно новый алгоритм разбиения.
Его характеристики следующие:
-
Параллелизм: в период сбора G1 несколько потоков GC могут работать одновременно, эффективно используя многоядерные вычислительные мощности.
-
Параллелизм: G1 имеет возможность чередовать выполнение с приложением, поэтому в целом приложение не будет полностью заблокировано на весь период сбора.
-
Поколение GC: В отличие от предыдущих сборщиков, другие сборщики работают либо в молодом поколении, либо в старом поколении. G1 может учитывать как молодое поколение, так и старое поколение.
-
Пространственная сортировка: G1 будет выполнять соответствующее перемещение объектов в процессе переработки. В отличие от CMS, это просто очистка меток. После нескольких сборок мусора CMS должна выполнить дефрагментацию. G1 будет эффективно копировать объекты при каждой переработке. Уменьшение космического мусора.
-
Предсказуемость: из-за разделения G1 может выбрать только часть области для высвобождения памяти, что уменьшает объем высвобождения, поэтому он также может лучше контролировать глобальную паузу.
1. Разделение памяти и основной процесс сбора G1
Сборщик-сборщик G1 разбивает кучу на отдельные области, при сборке собирается только несколько областей, чтобы контролировать время паузы сборки мусора.
Процесс сбора G1 может состоять из 4 фаз:
-
Кайнозойская ГК
-
параллельный цикл маркировки
-
смешанная коллекция
-
(при необходимости) Проведите полный сборщик мусора.
2. ГХ нового поколения G1
Основная работа ГК нового поколения заключается в переработке зоны Эдема и зоны выжившего.
Как только область Эдема заполнится, запустится GC нового поколения. Данные кучи до и после сбора GC в новом поколении показаны на следующем рисунке, где E представляет собой область eden, S представляет собой оставшуюся область, а O представляет старое поколение.
Видно, что ГХ нового поколения обрабатывает только области эден и выживших, после переработки все области эденов должны быть опустошены, а область выживших будет собирать часть данных, но должна быть еще хотя бы одна область выживших, по аналогии с другими коллекциями нового поколения, которые, кажется, не сильно изменились. Еще одним важным изменением является увеличение количества областей в старом поколении, потому что некоторые объекты в области выжившего или области эдема могут быть повышены до старого поколения.
3. Параллельный цикл маркировки G1
Параллельная фаза G1 несколько похожа на фазу CMS, чтобы сократить время паузы, а также извлечь и выполнить часть, которая может выполняться одновременно с приложением.
Параллельные циклы маркировки ориентированы на старое поколение
Параллельный цикл маркировки можно разделить на следующие этапы:
-
Начальная метка: помечайте объекты, которые напрямую доступны из корневого узла. Этот этап будет сопровождаться сборщиком мусора нового поколения, который вызовет глобальную паузу, и приложение должно прекратить выполнение на этом этапе.
-
Сканирование корневой области: поскольку начальная метка обязательно будет сопровождаться GC нового поколения, после начальной метки Эдем опустошается, а уцелевшие объекты перемещаются в оставшуюся область. На этом этапе будут сканироваться области старого поколения, непосредственно достижимые областью выживших, и эти непосредственно достижимые объекты будут отмечены. Этот процесс может выполняться одновременно с приложением. Однако сканирование корневой области не может выполняться одновременно со сборщиком мусора нового поколения (поскольку сканирование корневой области зависит от объектов в оставшейся области, и сборщик мусора нового поколения изменит эту область), поэтому, если произойдет сборщик мусора нового поколения чтобы быть необходимым в это время, GC должен дождаться окончания сканирования корневой области.Если это произойдет, время этого GC нового поколения будет продлено.
-
Параллельная маркировка: Подобно CMS, параллельная маркировка будет сканировать и находить активные объекты в куче и помечать их. Это параллельный процесс, и этот процесс может быть прерван GC молодого поколения.
-
Перемаркировка: Как и CMS, перемаркировка также приостанавливает работу приложения.Поскольку приложение все еще работает в процессе параллельной маркировки, может потребоваться корректировка результата маркировки, поэтому последняя маркировка дополняется на этом этапе. В G1 этот процесс осуществляется по алгоритму SATB (Snapshot-At-The-Begining), то есть G1 создает снимок живых объектов в начале маркировки, что помогает ускорить повторную маркировку.
-
Эксклюзивная очистка: как следует из названия, эта фаза вызывает паузу. Он рассчитает и отсортирует уцелевшие объекты и коэффициенты восстановления GC в каждом регионе, а также определит регионы, доступные для смешанного восстановления. На этом этапе также обновляется набор памяти. На этом этапе указываются и отмечаются области, которые необходимо смешать и рекультивировать, и эта информация необходима на этапе смешанной рекультивации.
-
Параллельная фаза очистки: определение и очистка полностью свободных областей. Это параллельная очистка, которая не вызывает зависаний.
Полное название SATB — Snapshot-At-The-Beginning, что буквально означает моментальный снимок объекта, который был активен на момент запуска GC. Его можно получить с помощью Root Tracing, и его роль заключается в поддержании правильности параллельного GC. Так как же он поддерживает правильность параллельного GC? По алгоритму трехцветной маркировки мы знаем, что объект имеет три состояния: белое: объект не маркируется, и после окончания фазы маркировки он будет собран как мусор. Серый: объект помечен, но его поля не помечены и не заполнены. Черный: объект отмечен, и все его поля отмечены.
SATB использует барьер записи для записи всех старых ссылок отношения ссылок, которые будут удалены, и, наконец, останавливает мир с этими старыми ссылками в качестве корня для повторного сканирования, чтобы избежать проблемы отсутствия меток. Следовательно, существует существенное различие между Stop The World в фазе G1 Remark и репликой CMS, то есть пауза нужна только для сканирования объекта, корнем которого является объект, преследуемый барьером записи, а реплика CMS необходимо повторно сканировать весь корневой набор, поэтому репликация CMS может выполняться очень медленно.
4. Смешанная переработка
В параллельном цикле маркировки, несмотря на то, что некоторые объекты перерабатываются, коэффициент переработки очень низок. Однако после цикла параллельной маркировки G1 уже знает, какие области содержат больше объектов мусора, и на этапе смешанной сборки может перерабатывать именно для этих областей. Конечно, G1 будет отдавать приоритет участкам переработки с более высокой долей мусора (переработка этих участков экономически эффективна), откуда и происходит название G1 (Garbage First Garbage Collector: переводится как сборщик мусора первым). , первый мусор (Garbage First Garbage Collector) здесь ) означает, что при переработке предпочтительно выбирается область с самым высоким коэффициентом мусора.
Этот этап называется смешанной рециркуляцией, потому что на этом этапе будет выполняться обычный GC молодого поколения, и для рециркуляции будут выбраны некоторые отмеченные области старого поколения, а новое поколение и старое поколение будут обрабатываться одновременно.
Смешанный сбор будет выполняться несколько раз, пока не будет освобождено достаточно места в памяти, а затем будет запущен сборщик мусора молодого поколения. После GC нового поколения может происходить параллельный цикл маркировки, и, наконец, произойдет смешанная переработка, поэтому весь процесс может быть следующим:
5. Полная сборка мусора при необходимости
Подобно CMS, параллельный сбор позволяет приложению и потокам GC работать попеременно, поэтому в ситуации особенной занятости неизбежно нехватка памяти во время процесса очистки.Когда это произойдет, G1 перейдет на полный сборщик мусора для повторного использования. .
Следующие 4 ситуации запускают этот тип полного GC:
1. Сбой параллельного режима
G1 начинает цикл маркировки, но перед Mix GC заполняется старое поколение, и в это время G1 отказывается от цикла маркировки. В этом случае нужно увеличить размер кучи или настроить цикл (например, увеличить количество потоков -XX:ConcGCThreads и т.д.).
Пример журнала GC выглядит следующим образом:
Обходной путь: Эта ошибка означает, что размер кучи должен был увеличиться, или что фоновая обработка сборщика G1 должна начинаться раньше, или что цикл необходимо скорректировать, чтобы он работал быстрее (например, увеличив количество потоков фоновой обработки).
2. Продвижение не удалось
(в пространство исчерпано или в пространство переполнено)
Сборщик G1 завершает фазу маркировки и запускает гибридную сборку мусора для очистки разделов старого поколения, однако пространство старого поколения будет исчерпано до того, как сборщик мусора освободит достаточно памяти. (G1 не хватает памяти для выживших или продвинутых объектов во время сборки мусора), что запускает полную сборку мусора.
В следующем журнале (в журнале вы можете увидеть (исчерпание пространства) или (переполнение пространства)) феномен реакции заключается в том, что за смешанным сборщиком мусора следует полный сборщик мусора.
Этот сбой обычно означает, что гибридная сборка должна завершить сборку мусора быстрее: каждой сборке мусора нового поколения необходимо обработать больше разделов старого поколения.
Способ решения этой проблемы:
-
Увеличьте значение параметра -XX:G1ReservePercent (и соответственно увеличьте общий размер кучи), чтобы увеличить объем зарезервированной памяти для «целевого пространства».
-
Запустите цикл маркировки раньше, уменьшив -XX:InitiatingHeapOccupancyPercent.
-
Количество параллельных отмеченных потоков также можно увеличить, увеличив значение параметра -XX:ConcGCThreads.
3. Эвакуация не удалась
(в пространство исчерпано или в пространство переполнено)
Для сборки мусора молодого поколения в пространстве Survivor недостаточно места, а старому поколению не хватает места для хранения всех уцелевших объектов. Обычно это происходит в журнале GC:
Этот журнал указывает, что куча почти полностью исчерпана или фрагментирована. Сборщик G1 попытается исправить этот сбой, но можно ожидать, что результат будет хуже: сборщик G1 переключится на Full GC.
Способ решения этой проблемы:
-
Увеличьте значение параметра -XX:G1ReservePercent (и соответственно увеличьте общий размер кучи), чтобы увеличить объем зарезервированной памяти для «целевого пространства».
-
Запустите цикл маркировки раньше, уменьшив -XX:InitiatingHeapOccupancyPercent.
-
Количество параллельных отмеченных потоков также можно увеличить, увеличив значение параметра -XX:ConcGCThreads.
4. Не удалось выделить огромный объект
Когда огромный объект не может найти подходящее место для выделения, он запускает полный сборщик мусора, чтобы освободить место. В этом случае следует избегать размещения большого количества объектов-гигантов, увеличивать объем памяти или увеличивать -XX:G1HeapRegionSize, чтобы объект-гигант перестал быть объектом-гигантом.
Другой способ справиться с огромными объектами — переключить алгоритм GC на ZGC, потому что ZGC не имеет специальной обработки для восстановления огромных объектов (например, без отложенного сбора).
6. Гигантские объекты
Огромный объект: огромный объект Огромные регионы: гигантские регионы
Для G1, если он превышает половину размера региона, он считается гигантским объектом. Jumbo-объекты размещаются непосредственно в «гигантских регионах» в старом поколении. Эти гигантские регионы представляют собой непрерывный набор регионов. StartsHumongous отмечает начало набора продолжений, а ContinuesHumongous отмечает его продолжение.
Перед выделением больших объектов проверьте, не превышены ли начальный процент заполнения кучи и порог маркировки.Если он превышается, запускается глобальная параллельная маркировка для раннего перезапуска и предотвращения сбоев очистки и полного GC.
Для гигантских объектов следует отметить несколько моментов:
-
Огромные объекты, на которые нет ссылок, будут освобождены на этапе очистки разметки или во время полной сборки мусора.
-
Чтобы уменьшить нагрузку при копировании, большие области объектов сжимаются только во время полного GC.
-
В каждом регионе есть только один гигантский объект, а остальная часть региона не используется, что приводит к фрагментации кучи.
-
Если вы видите частые одновременные коллекции из-за выделения больших объектов, вам необходимо преобразовать большие объекты в обычные объекты.Рекомендуется увеличить размер области. (или переключиться на ZGC)
Одним из негативных последствий увеличения размера региона является уменьшение количества доступных регионов. Таким образом, в этом случае вам необходимо провести соответствующее тестирование, чтобы увидеть, действительно ли вы улучшите пропускную способность или задержку своего приложения.
Семь, общие параметры настройки
1. -XX:MaxGCPauseMillis=N
По умолчанию 200 мс
Самые основные параметры для использования GC были введены ранее:
-XX:+UseG1GC -Xmx32g -XX:MaxGCPauseMillis=200
Первые два параметра понятны, как настроить последний параметр MaxGCPauseMillis? Этот параметр буквально означает максимально допустимое время паузы сборщика мусора. G1 пытается убедиться, что время каждой паузы GC находится в пределах установленного MaxGCPauseMillis. Так как же G1 достигает максимального времени паузы? Это включает в себя другое понятие, CSet (набор коллекций). Имеется в виду совокупность регионов, которые собираются в одном сборщике мусора.
-
Молодой ГК: выберите все регионы в молодом поколении. Накладные расходы молодого GC контролируются путем контроля количества регионов в новом поколении.
-
Смешанный GC: выберите все регионы нового поколения, а также некоторые регионы старого поколения с высоким доходом от сбора в соответствии с глобальной статистикой одновременной маркировки. Выберите регион старого поколения с самой высокой доходностью, насколько это возможно в рамках заданной пользователем цели затрат.
Поняв это, мы устанавливаем максимальное время паузы, чтобы иметь направление. Прежде всего, существует ограничение на максимальное время паузы, которое мы можем выдержать, и нам нужно установить его в пределах этого ограничения. Но какое значение должно быть установлено? Нам нужно сделать баланс между пропускной способностью и MaxGCPauseMillis. Если для параметра MaxGCPauseMillis установлено слишком малое значение, сборка мусора будет выполняться часто, а пропускная способность упадет. Если для MaxGCPauseMillis задано слишком большое значение, время паузы приложения будет больше. Время паузы по умолчанию для G1 составляет 200 миллисекунд, мы можем начать отсюда и настроить подходящее время.
2. -XX:G1HeapRegionSize=n
Установите размер области G1. Значения являются степенью двойки и варьируются от 1 МБ до 32 МБ. Цель состоит в том, чтобы выделить около 2048 регионов на основе наименьшего размера кучи Java.
- -XX:ParallelGCThreads=n (настроить количество фоновых потоков для сборки мусора G1)
Задает значение количества рабочих потоков STW. Установите значение n равным количеству логических процессоров. Значение n равно количеству логических процессоров, но не более 8.
Если имеется более восьми логических процессоров, установите значение n примерно равным 5/8 от числа логических процессоров. Это работает в большинстве случаев, за исключением более крупных систем SPARC, где значение n может составлять около 5/16 от числа логических процессоров.
-XX:ConcGCThreads=n (настроить количество фоновых потоков для сборки мусора G1)
Устанавливает количество потоков, отмеченных параллельно. Задайте для n примерно 1/4 количества параллельных потоков сборки мусора (ParallelGCThreads).
3. -XX:InitiatingHeapOccupancyPercent=45 (настроить частоту операции сборки мусора G1)
Устанавливает порог занятости кучи Java, который запускает цикл маркировки. Занятость по умолчанию составляет 45% всей кучи Java.
Установите это значение слишком большим: вы застрянете в трясине Full GC, потому что параллельной фазе не хватит времени для завершения сборки мусора до того, как оставшееся пространство кучи будет заполнено.
Если значение установлено слишком низким: приложение снова будет выполнять много фоновой обработки с частотой, превышающей фактически необходимую.
Избегайте следующих параметров: Избегайте явной установки размера молодого поколения с помощью параметра -Xmn или других связанных параметров, таких как -XX:NewRatio. Фиксация размера молодого поколения переопределяет целевое время паузы.
8. Детали
1. Когда G1 смешанный GC?
Существует также пороговый параметр -XX:InitiatingHeapOccupancyPercent в смешанном сборщике мусора.Когда процентное соотношение старости ко всему размеру кучи достигает этого порога, будет запущен смешанный сборщик мусора.
Перед размещением огромного объекта проверьте, не превышен ли начальный процент заполнения кучи.Если он превышает, запускается глобальная параллельная маркировка, чтобы восстановиться раньше и предотвратить сбои эвакуации и полный сборщик мусора.
Чтобы уменьшить влияние непрерывного выделения H-объектов на GC, необходимо преобразовать большие объекты в обычные объекты, рекомендуется увеличить размер области.
Размер региона может быть установлен параметром -XX:G1HeapRegionSize, значение находится в диапазоне от 1M до 32M и является индексом 2.
2. XX: Значение по умолчанию для G1 HeapRegionSize?
По умолчанию память кучи делится на 2048 частей, и в итоге получается разумный размер.
3. Прямая конфигурация памяти
В: Когда использовать прямую память?
О: В случае частого чтения и записи по соображениям производительности можно рассмотреть возможность использования прямой памяти.
Прямая память также является очень важной частью программ Java, особенно после того, как NIO широко используется, прямая память может пропускать кучу Java, позволяя программам Java напрямую обращаться к собственному пространству кучи. Следовательно, скорость доступа к памяти может быть в определенной степени ускорена. Прямая память может быть установлена с помощью -XX:MaxDirectMemorySize, значением по умолчанию является максимальное пространство кучи, которое равно -Xmx. Когда прямая память достигает максимального значения, также будет запущена сборка мусора.Если сборка мусора не может эффективно освободить пространство, прямое переполнение памяти все равно вызовет OOM системы.
Вообще говоря, прямая память имеет большее преимущество (более высокая скорость) при доступе к чтению и записи, но при использовании памяти прямая память не имеет преимущества.
4. RSet
Полное название — «Запомненный набор», представляющий собой структуру, помогающую процессу GC.Типичный инструмент «пространство-время» чем-то похож на карточную таблицу. RSet G1 реализован на основе таблицы карт: каждый регион будет записывать, что другие регионы имеют указатели на себя, и отмечать, в каких диапазонах карт находятся эти указатели. Этот RSet на самом деле является хэш-таблицей, ключ — начальным адресом других регионов, значение — набором, а элементы в нем — индексом карточной таблицы.
Как именно RSet помогает GC?
При выполнении YGC в качестве корневого набора необходимо выбрать только RSet региона молодого поколения.Эти RSets записывают межпоколенческие ссылки old->young, избегая сканирования всего старого поколения. В смешанном gc старый->старый RSet записывается в старом поколении, а молодой->старый эталон получается путем сканирования всех регионов молодого поколения, так что нет необходимости сканировать все регионы старого поколения. Поэтому введение RSet значительно снижает нагрузку на GC.
9. Новые возможности G1 в JDK 12
1. Прервать смешанный сборщик мусора
G1 смешанного GC может быть прерван, если есть возможность превысить цель паузы.
2. G1 возвращает сразу, не используя выделенную память
Усовершенствуйте сборщик мусора G1, чтобы он автоматически возвращал память кучи Java в операционную систему при простое.
10. Тенденция развития ГК
На самом деле, мы можем видеть тенденцию сборщика мусора Java, которая заключается в том, чтобы максимально уменьшить влияние GC на приложение в предпосылке большой кучи памяти; от поэтапной инкрементной маркировки CMS до G1, исправляющего Stop Theory на этапе замечания через алгоритм SATB World's effect, до ZGC/C4 даже без Stop The World на этапе маркировки и так далее.
Одиннадцать, конец
Существует несколько рекомендуемых способов изучения этого GC:
-
См. JEP (предложение по улучшению JDK), чтобы узнать о его тонкостях.
-
Глядя на документ соответствующего алгоритма (когда я раньше читал документ Shenandoah GC Paper, я почувствовал большую выгоду, потому что метод обработки Shenandoah GC находится между G1 и ZGC, поэтому после прочтения Shenandoah GC Paper я чувствую, что G1, ZGC лучше понимает).
В конце статьи я добавлю некоторые данные GC (в том числе некоторые бумажные) адреса github, собранные адресом официального сайта JEP вместе со мной.
Составьте диаграмму GC, которую я обобщил сам:
Различные алгоритмы GC вращаются вокруг содержимого на рисунке, но их методы обработки различны.
Рекомендуемые данные:
1. Алгоритм GC и статья
2. Рекомендуемые книги по Java
использованная литература
1. Практическая диагностика неисправностей виртуальной машины JAVA JVM и оптимизация производительности
2. джипы
3. Другое
PLU MBR.IO/handbook/ только что…
12. Информация о блогере
Личный публичный аккаунт WeChat: