Нажмите, чтобы просмотреть полные заметки об исследовании JVM
Классификация и показатели эффективности ГК
- Сборщик мусора не слишком подробно описан в спецификации и может быть реализован разными производителями и разными версиями JVM.
- Поскольку версия JDK находится в процессе быстрой итерации, разработка Java породила множество версий GC.
- Анализируя сборщик мусора с разных сторон, GC можно разделить на разные типы.
По количеству потоков его можно разделить на последовательный сборщик мусора и параллельный сборщик мусора.
- Последовательная сборка означает, что только один ЦП может выполнять операции по сборке мусора в один и тот же период времени, а рабочие потоки приостанавливаются до окончания работы по сборке мусора.
- ➢В тех областях, где аппаратные платформы, такие как однопроцессорные процессоры или меньшая память приложений, не имеют особых преимуществ Комбинированные последовательные сборщики могут превзойти параллельные сборщики и параллельные сборщики. Поэтому последовательная переработка применяется по умолчанию в JVM в клиентском режиме клиента
- ➢ На ЦП с сильным параллелизмом время паузы, генерируемое параллельным коллектором, короче, чем у последовательного коллектора.
- В отличие от последовательной сборки, параллельная сборка может использовать несколько процессоров для одновременной сборки мусора, что улучшает Пропускная способность приложения улучшена, но параллельная переработка остается такой же, как и последовательная переработка, которая принимает эксклюзивный режим и использует механизм «Остановить мир».
По режиму работы его можно разделить на параллельный сборщик мусора и монопольный сборщик мусора.
- Параллельные сборщики мусора работают попеременно с потоками приложения, чтобы свести к минимуму время простоя приложения.
- После запуска эксклюзивного сборщика мусора (Stop the world) он останавливает все пользовательские потоки в приложении до тех пор, пока процесс сборки мусора не будет полностью завершен.
По способу фрагментации его можно разделить на сжимающий сборщик мусора и несжимающий сборщик мусора.
- Уплотняющий сборщик мусора будет сжимать уцелевшие объекты после завершения утилизации, чтобы удалить фрагменты после утилизации.
- RealLocate Object Space Использование: Столкновение указателя
- Неуплотняющий сборщик мусора этого не делает.
- Использование перераспределенного пространства объекта: свободный список
По объему рабочей памяти ее можно разделить на сборщики мусора молодого поколения и сборщики мусора старого поколения.
Оценка показателей производительности GC
-
== Пропускная способность: время, затраченное на выполнение пользовательского кода, в процентах от общего времени выполнения ==
- (Общее время работы: время работы программы десять раз восстановления памяти)
-
Накладные расходы на сборку мусора: дополнение к пропускной способности, отношение времени, затрачиваемого на сборку мусора, к общему времени работы.
-
== Время паузы: время, в течение которого рабочие потоки программы приостанавливаются, пока выполняется сборка мусора ==
-
Частота сбора: как часто выполняются операции сбора по отношению к выполнению приложения.
-
==Объем памяти: объем памяти, занимаемый областью кучи Java==
-
Быстро: время, прошедшее между рождением объекта и его сбором.
-
Эти трое вместе образуют «невозможный треугольник». Общая производительность всех трех будет становиться все лучше и лучше с развитием технологий. Хороший коллекционер обычно удовлетворяет не более чем двум из них.
-
Среди этих трех пунктов важность тайм-аута становится все более заметной. Поскольку с развитием аппаратного обеспечения использование памяти Все более и более терпимые аппаратные улучшения производительности также помогают уменьшить влияние среды выполнения сборщика на приложение, т. е. увеличить пропускную способность. Расширение памяти негативно сказывается на задержке.
-
Проще говоря, мы в основном фокусируемся на двух моментах:
- пропускная способность
- Время паузы
пропускная способность
- Пропускная способность — это отношение времени, которое ЦП использует для выполнения пользовательского кода, к общему времени использования ЦП, то есть пропускная способность = время выполнения пользовательского кода / (время выполнения пользовательского кода + время сборки мусора).
- ➢ Например: виртуальная машина работает в общей сложности 100 минут, из которых сборка мусора занимает 1 минуту, тогда пропускная способность составляет 99%
- В этом случае приложение может выдерживать более длительное время паузы, поэтому приложения с высокой пропускной способностью имеют более длительные тесты времени, а быстрый отклик не является проблемой.
- Сначала пропускная способность, что означает, что в единицу времени STW имеет самое короткое время: 0,2 + 0,2 = 0,4.
Время паузы
- «Время паузы» относится к состоянию, в котором поток приложения приостанавливается на определенный период времени, что позволяет потоку GC выполняться.
- ➢ Например, пауза в 100 мс во время сборки мусора означает, что в течение этого периода 100 мс ни один поток приложения не активен. .
- Сначала сделайте паузу, что означает максимально возможное сокращение одного STW: 0,1 + 0,1 + 0,1 + 0,1+0,1=0,5
- Высокая пропускная способность лучше, потому что конечный пользователь приложения чувствует, что только поток приложения выполняет «продуктивную» работу. Интуитивно понятно, что чем выше пропускная способность, тем быстрее будет работать программа.
- Малое время паузы (малая задержка) лучше, потому что с точки зрения конечного пользователя всегда плохо, когда приложение приостанавливается либо из-за GC, либо по другим причинам. В зависимости от типа приложения иногда даже короткая пауза в 200 мс может нарушить работу конечного пользователя. Поэтому очень важно иметь малое время большой паузы, особенно для интерактивного приложения.
- К сожалению, «высокая пропускная способность» и «малое время пауз» — это пара конкурирующих целей (парадокс).
- ➢Потому что, если вы выберете приоритет пропускной способности, вы должны уменьшить частоту выполнения освобождения памяти, но это приведет к тому, что GC потребуется более длительная пауза для выполнения освобождения памяти.
- ➢ Наоборот, если в качестве принципа выбран принцип малой латентности, то для уменьшения времени паузы каждой регенерации памяти, регенерация памяти может выполняться только часто, но это вызовет усадку памяти молодого поколения и привести к снижению пропускной способности программы.
- При разработке (или использовании) алгоритма GC мы должны определить наши цели: алгоритм GC может быть нацелен только на одну из двух целей (т. е. фокусироваться только на большей пропускной способности или минимальном времени паузы) или пытаться найти компромисс между обеими задачами.
- Теперь в стандарте: сократите время пауз, когда приоритетом является максимальная пропускная способность.
Обзор различных сборщиков мусора
Механизм сборки мусора — это сигнатурная возможность Java, которая значительно повышает эффективность разработки. Это, конечно, также горячая тема интервью.
Итак, каковы общие сборщики мусора в Java?
История сборщика мусора
С виртуальной машиной должен требоваться механизм сборки мусора, которым является Garbage Collection, и соответствующий продукт называется Garbage Collector.
- В 1999 году с JDK1.3.1 появился Serial GC в последовательном режиме, который был первым GC. Сборщик мусора ParNew — это многопоточная версия сборщика мусора Serial.
- 26 февраля 2002 г. были выпущены Parallel GC и Concurrent Mark Sweep GC вместе с JDK1.4.2.
- Параллельный сборщик мусора стал сборщиком мусора HotSpot по умолчанию после JDK6.
- В 2012 году в выпуске JDK1.7u4 был доступен G1.
- В 2017 году G1 стал сборщиком мусора по умолчанию в JDK9, заменив CMS.
- В марте 2018 года была запущена параллельная полная сборка мусора для сборщика мусора G1 в JDK10, что позволило параллелизму уменьшить задержку в наихудшем случае.
- ==----------- Водораздел -------------==
- В сентябре 2018 года был выпущен JDK11. Представлен сборщик мусора Epsilon, также известный как сборщик «No-Op (No-Op)». В то же время представлен ZGC: масштабируемый сборщик мусора с малой задержкой (экспериментальный).
- В марте 2019 года был выпущен JDK12. Усовершенствованный G1 для автоматического возврата неиспользуемой памяти кучи в операционную систему. В то же время вводится GC Shenandoah: GC с малым временем паузы (Experimental).
- В сентябре 2019 года был выпущен JDK13. Усовершенствованный ZGC для автоматического возврата неиспользуемой динамической памяти в операционную систему.
- В марте 2020 года был выпущен JDK14. Удалите сборщик мусора CMS. Расширьте приложение ZGC на macOS и Windows.
7 классических сборщиков мусора
- Серийный коллекционер: Серийный.Серийный Старый
- Parallel Scavenger: ParNew, Parallel Scavenge, Parallel Old
- Параллельный коллектор: CMS.G1
Связь между 7 классическими сборщиками мусора и генерацией мусора
- Сборщики нового поколения: Serial, ParNeW, Parallel Scavenge;
- Сборщики старого поколения: Serial 0ld, Parallel 0ld, CMS;
- Сборщик всей кучи: G1;
Комбинация сборщиков мусора
- Между двумя коллекторами есть связь, указывающая на то, что их можно использовать вместе: Серийный/Серийный 01d, Серийный/CMS, ParNew/Серийный 01d, ParNew/CMS, Параллельная уборка/Серийный 01d, Параллельная уборка/Параллельная 0ld, G1;
- Серийный номер 0ld используется в качестве плана резервного копирования на случай сбоя «Сбой параллельного режима» в CMS. 3. (красная пунктирная линия) Из-за стоимости обслуживания и тестирования совместимости Serial+CMS, Две комбинации ParNew+Serial 01d объявлены устаревшими (JEP 173), а поддержка этих комбинаций полностью исключена из JDK 9 (JEP214), т. е. удалена.
- (зеленая пунктирная линия) В JDK 14: устаревшая комбинация Parallel Scavenge и Serial0ld GC (JEP366)
- (голубая пунктирная линия) JDK 14: удаление сборщика мусора CMS (JEP 363)
- Почему у вас много коллекционеров? Поскольку сценарии использования Java, мобильные терминалы, серверы и т. Д. Следовательно, вам необходимо обеспечить различные сборщики мусора для разных сценариев, улучшают производительность сборки мусора.
- Пока мы сравниваем коллекторы, мы не пытаемся выбрать лучший. Не существует универсального идеального коллектора, применимого к любому сценарию, и не существует такой вещи, как универсальный коллектор. Поэтому мы выбираем только наиболее подходящий коллектор для конкретного применения.
Просмотр сборщика мусора по умолчанию
- One xx: +PrintCommandLineFlags: просмотр параметров, связанных с командной строкой (включая используемый сборщик мусора).
- Используйте команду командной строки: jinfo флаг, связанный с параметрами сборщика мусора, идентификатор процесса
/**
* -XX:+PrintCommandLineFlags
*
* -XX:+UseSerialGC:表明新生代使用Serial GC ,同时老年代使用Serial Old GC
*
* -XX:+UseParNewGC:标明新生代使用ParNew GC
*
* -XX:+UseParallelGC:表明新生代使用Parallel GC
* -XX:+UseParallelOldGC : 表明老年代使用 Parallel Old GC
* 说明:二者可以相互激活
*
* -XX:+UseConcMarkSweepGC:表明老年代使用CMS GC。同时,年轻代会触发对ParNew 的使用
*/
public class GCUseTest {
public static void main(String[] args) {
ArrayList<byte[]> list = new ArrayList<>();
while(true){
byte[] arr = new byte[100];
list.add(arr);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
вывод
-XX:InitialHeapSize=268435456 -XX:MaxHeapSize=4294967296 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC
или командная строка
JDK8 использует параллельный
JDK9 — это G1.
Серийный переработчик: серийная переработка
- Сборщик Serial — самый простой и самый старый сборщик мусора. До JDK1.3 единственным вариантом было переработать новое поколение.
- Последовательный сборщик — это сборщик мусора молодого поколения по умолчанию в режиме клиента в HotSpot.
- Последовательный сборщик использует алгоритм репликации, последовательный сбор и механизм «Stop-the-World» для выполнения сбора памяти. )
- В дополнение к молодому поколению сборщик Serial также предоставляет сборщик Serial 0ld для выполнения сборки мусора старого поколения. Сборщик Serial 0ld также использует серийную переработку.
и механизм «Остановить мир», за исключением того, что алгоритм восстановления памяти использует алгоритм сжатия меток.
Закон.
- ➢Serial 0ld — сборщик мусора старого поколения по умолчанию, работающий в клиентском режиме.
- ➢Serial 0ld имеет два основных назначения в режиме сервера: ① Используется совместно с ParallelScavenge нового поколения ② Используется как резервная схема сборки мусора для CMS сборщика старого поколения
- Этот сборщик является однопоточным сборщиком, но его «однопоточный» смысл означает не только то, что он будет использовать только один ЦП или один поток сбора для завершения работы по сборке мусора, но, что более важно, когда он выполняет сборку мусора, все остальные рабочие потоки должны быть приостановлены до тех пор, пока они не закончат сбор (Stop The World).
Преимущество
- Простой и эффективный (по сравнению с коэффициентом однопоточности других сборщиков), для среды, ограниченной одним ЦП, сборщик Seria1 не требует дополнительных затрат на взаимодействие потоков, поэтому естественно сконцентрироваться на сборке мусора для достижения максимальной однопоточности. эффективность сбора.
- ➢Хорошим выбором будет виртуальная машина, работающая в режиме клиента.
- В сценарии пользовательского настольного приложения доступная память обычно невелика (от десятков МБ до одной или двухсот МБ), Сборка мусора может быть завершена за относительно короткое время (от десятков мс до более 100 мс), и если это происходит нечасто, допустимо использовать последовательный сборщик.
- В виртуальной машине HotSpot с помощью параметра XX: + UseSerialGC укажите, что старое и молодое поколение используют последовательный коллектор.
- Это эквивалентно использованию Serial GC для молодого поколения и Serial 0ld GC для старого поколения.
- консольный вывод
-XX:InitialHeapSize=268435456 -XX:MaxHeapSize=4294967296 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseSerialGC
Суммировать
- Мы все знаем этот сборщик мусора, и он уже не серийный. И его можно использовать только на ограниченном одноядерном процессоре. Это уже не одноядерник.
- Такие сборщики мусора неприемлемы для интерактивных приложений. T обычно не использует последовательные сборщики мусора в веб-приложениях Java.
ParNew Collector: Параллельная коллекция
-
Если Serial GC — это однопоточный сборщик мусора молодого поколения, то сборщик ParNew — это многопоточная версия сборщика Serial.
- ➢Par — это сокращение от Parallel1, New: может обрабатываться только новое поколение
-
Между двумя сборщиками мусора почти нет разницы, за исключением того, что сборщик ParNew выполняет освобождение памяти параллельно. Сборщик ParNew также использует алгоритм репликации и механизм «Stop-the-World» в молодом поколении.
-
ParNew — это сборщик мусора по умолчанию для молодого поколения многих JVM, работающих в режиме сервера.
-
Для молодого поколения количество коллекций частое, а параллельный метод эффективен.
-
Для старого поколения количество рециклов невелико, а серийный режим используется для экономии ресурсов. (Параллельный процессор должен переключать потоки, последовательный может сэкономить ресурсы переключения потоков)
-
Поскольку сборщик ParNew основан на параллельном сборе, можно ли сделать вывод, что эффективность сбора у сборщика ParNew будет выше, чем у последовательного сборщика в любом сценарии? |я
- ➢Коллектор ParNew работает в многопроцессорной среде, поскольку он может полностью использовать Преимущества физических аппаратных ресурсов, таких как многоядерность, могут ускорить сборку мусора и повысить производительность программы.
- ➢ Но в среде одного ЦП коллектор ParNew не выше, чем коллектор Serial эффект. Несмотря на то, что сборщик Serial основан на повторном использовании последовательного интерфейса, поскольку центральному процессору не нужно часто переключать задачи, он может эффективно избежать некоторых дополнительных накладных расходов в процессе многопоточного взаимодействия.
-
Потому что, кроме Serial, на данный момент только ParNew GC может работать с сборщиком CMS.
-
В программе разработчики могут вручную указать использование сборщика .ParNew для выполнения задач по высвобождению памяти через опцию «One XX: +UseParNewGC». Это указывает на то, что молодое поколение использует параллельный коллектор и не влияет на старое поколение.
-
One XX: ParallelGCThreads Ограничивает количество потоков, и по умолчанию включено то же количество потоков, что и данные ЦП. .
Параллельный коллектор: сначала производительность
- В дополнение к сборщику ParNew в новом поколении HotSpot, основанном на параллельном сборе, Сборщик Parallel Scavenge также использует алгоритм репликации, параллельную переработку и механизм «Остановить мир».
- Так что появление коллектора Parallel лишнее?
- ➢ В отличие от сборщика ParNew, целью сборщика Parallel Scavenge является достижение контролируемой пропускной способности==(Throughput), которая также известна как сборщик мусора с приоритетом пропускной способности.
- ➢Стратегия адаптивной корректировки также является важным отличием Parallel Scavenge от ParNew.
- Высокая пропускная способность позволяет эффективно использовать процессорное время для скорейшего завершения вычислительных задач программы | Подойдет для задач, которые работают в фоновом режиме без особого взаимодействия. Поэтому он обычно используется в серверных средах. Например, приложения, выполняющие пакетную обработку, обработку заказов, начисление заработной платы, научные вычисления.
- Сборщик Parallel был предоставлен в JDK 1.6 для выполнения сборки мусора старого поколения. Коллектор Parallel 0ld, используемый для замены старого коллектора Serial 0ld.
- Сборщик Parallel 0ld использует алгоритм сжатия меток, но также основан на параллельной переработке и механизме «Stop-the-World».
- В сценарии приложений, где производительность программы является приоритетом, комбинация сборщика Parallel и сборщика Parallel 0ld обеспечивает очень хорошую производительность восстановления памяти в режиме сервера.
- В Java8 по умолчанию используется этот сборщик мусора.
конфигурация параметров
- A XX: +UseParallelGC вручную указывает, что молодое поколение использует параллельный сборщик Parallel для выполнения задач высвобождения памяти.
- A XX: +UseParallel0ldGc Вручную укажите, что старое поколение должно использовать сборщик параллельных коллекций.
- Относится к новому поколению и старому поколению соответственно. По умолчанию jdk8 включен.
- Для двух вышеуказанных параметров один включен по умолчанию, а другой также включен. (активируя друг друга)
- A XX: ParallelGCThreads задает количество потоков для параллельного сборщика молодого поколения. Как правило, лучше всего равняться количеству ЦП, чтобы избежать слишком большого количества потоков, влияющих на производительность сборки мусора.
- По умолчанию, когда количество ЦП меньше 8, значение Parallel GCThreads равно количеству ЦП.
- Когда количество ЦП больше 8, значение ParallelGCThreads равно 3+[5*CPU_ Count]/8].
- A XX: MaxGCPau3eMillis устанавливает максимальное время паузы сборщика мусора (т.е. время STw). Единица измерения — миллисекунды.
- ➢ Чтобы максимально контролировать время паузы в MaxGCPauseMills, сборщик будет регулировать размер кучи Java или некоторые другие параметры при работе.
- ➢ Для пользователей чем короче время паузы, тем лучше впечатления. Но на стороне сервера мы сосредоточимся на Высокий параллелизм, общая пропускная способность. Поэтому серверная часть подходит для управления Parallel. ➢Используйте этот параметр с осторожностью.
- A XX: GCTimeRatio Отношение времени сборки мусора к общему времени (= 1 / (N + 1)) используется для измерения размера пропускной способности.
- ➢Диапазон значений (0, 100). Значение по умолчанию — 99, что означает, что время сборки мусора не превышает 1.
- ➢Есть определенное противоречие с предыдущим параметром XX:MaxGCPauseMillis. Чем больше время паузы, тем легче параметру Radio превысить установленное соотношение.
- One XX: +UseAdaptiveSizePolicy установить сборщик Parallel Scavenge с адаптивной политикой корректировки
- В этом режиме размер молодого поколения, соотношение Эдема и Выжившего, поощрение старости Такие параметры, как возраст объекта генерации, автоматически корректируются для достижения баланса между размером кучи, пропускной способностью и временем паузы.
- В случаях, когда ручная настройка затруднена, этот адаптивный метод можно использовать напрямую. Установите максимальную кучу, целевую пропускную способность (GCTimeRatio) и время паузы (MaxGCPauseMills) виртуальной машины и позвольте виртуальной машине выполнить настройку самостоятельно.
Сборщик CMS: низкая задержка
- В период JDK1.5 HotSpot выпустила программное обеспечение, которое можно рассматривать как стратегию в приложениях с сильным взаимодействием. Сборщик мусора эпохи: сборщик CMS (Concurrent-Mark-Sweep), этот сборщик является первым настоящим параллельным сборщиком в виртуальной машине HotSpot, это первый случай, когда поток сборки мусора и пользовательские потоки работают одновременно.
- Задача сборщика CMS — свести к минимуму время паузы пользовательских потоков во время сборки мусора. при паузе
Чем короче время (низкая задержка), тем больше подходит для программ, которые взаимодействуют с пользователем, а хорошая скорость отклика может улучшить взаимодействие с пользователем.
- ➢ В настоящее время большая часть Java-приложений сосредоточена на серверной стороне интернет-сайтов или систем B/s.Такие приложения уделяют особое внимание скорости отклика сервисов и рассчитывают, что время паузы системы будет кратчайшим, чтобы пользователи могли лучший опыт. Сборщик CMS очень подходит для нужд этого типа приложений.
- Алгоритм сборки мусора CMS использует алгоритм пометки и очистки, а также «остановить мир».
- К сожалению, CMS, как сборщик старого поколения, не может работать с уже существующим в JDK 1.4.0 сборщиком нового поколения Parallel Scavenge, поэтому при использовании CMS для сбора старого поколения в JDK 1.5 новое поколение Можно выбрать коллекторы ParNew или Serial.
- До появления G1 CMS все еще очень широко использовалась. По сей день существует множество систем, использующих CMS GC.
Весь процесс CMS более сложен, чем предыдущий сборщик, и весь процесс разделен на 4 основных этапа, а именно этап начальной маркировки, этап одновременной маркировки, этап повторной маркировки и этап одновременной очистки.
- Фаза начальной метки (Initial-Mark): на этой фазе все рабочие потоки в программе будут связаны с . Небольшая пауза из-за механизма "Stop-the-World" Основная задача этого этапа - просто пометить объекты, с которыми GCRoots может напрямую ассоциироваться. После завершения маркировки все приложения и потоки, которые ранее были приостановлены, будут возобновлены. Поскольку напрямую связанный объект относительно мал, здесь он работает очень быстро.
- Этап Concurrent mark (Concurrent-Mark): пройти всю пару от непосредственно связанного объекта GC Roots Как и процесс графа, этот процесс занимает много времени, но не требует приостановки пользовательского потока и может выполняться одновременно с потоком сборки мусора.
- Фаза примечания: Поскольку на этапе параллельной маркировки рабочий поток программы будет выполняться одновременно или перекрестно с потоком сборки мусора, поэтому для исправления части объектов, помеченных изменениями, в связи с продолжением работы программа пользователя во время периода параллельной маркировки Время паузы на этом этапе обычно немного больше, чем на начальной фазе маркировки, но оно также намного короче, чем фаза параллельной маркировки.
- Фаза параллельной очистки (Concurrent-Sweep): эта фаза очищает и удаляет мертвые объекты, оцененные на этапе маркировки, и освобождает пространство памяти. Поскольку нет необходимости перемещать живые объекты, этот этап также может выполняться одновременно с пользовательскими потоками.
Хотя сборщик CMS использует одновременную перезапись (включительно), ему все же необходимо выполнить механизм «Stop-the-World» для приостановки рабочих потоков в программе на двух этапах ее инициализации, маркировки и перемаркировки, но время паузы Это не будет слишком долго, так что можно сказать, что все нынешние сборщики мусора вообще не умеют делать «Остановить мир», но максимально сокращают время паузы.
Поскольку наиболее трудоемкие этапы одновременной маркировки и одновременной очистки не требуют приостановки работы, общий сбор выполняется с малой паузой.
Кроме того, поскольку пользовательский поток не прерывается на этапе сборки мусора, в процессе очистки CMS также следует убедиться, что пользовательский поток приложения имеет достаточно доступной памяти. Поэтому сборщик CMS не может ждать, пока старое поколение почти полностью заполнится перед сбором, как другие сборщики, а начинает собирать, когда использование памяти кучи достигает определенного порога, чтобы гарантировать, что приложение находится в процессе работы CMS. достаточно места для запуска приложения. Если память, зарезервированная во время работы CMS, не может удовлетворить потребности программы, произойдет сбой «Сбой параллельного режима».В это время виртуальная машина запустит план резервного копирования: временно включите сборщик Serial 0ld для перезапуска мусора старого поколения. сбор, так что пауза Это было давно.
Алгоритм сборки мусора сборщика CMS использует алгоритм маркировки-очистки, что означает, что после каждого выполнения освобождения памяти пространство памяти, занимаемое бесполезными объектами, которые выполняют освобождение памяти, скорее всего, будет некоторыми прерывистыми блоками памяти. будет некоторая фрагментация памяти. Тогда CMS не сможет использовать метод Bump the Pointer при выделении памяти для нового объекта, а сможет только выбрать Free List для выполнения выделения памяти.
Некоторые люди могут подумать, что раз Mark Sweep вызовет фрагментацию памяти, то почему бы не заменить алгоритм на Mark Compact?
答案其实很简答,因为当并发清除的时候,用Compact整理内存的话,原来的用户线程使用的内存还怎么用呢?要保证用户线程能继续执行,前提的它运行的资源不受影响嘛。Mark Compact更适合“Stop the World”这种场景”下使用
Преимущества CMS: .
- параллельный сбор
- низкая задержка
Недостатки CMS:
- 1) Произойдет фрагментация памяти, что приведет к нехватке места для пользовательских потоков после одновременной очистки. В случае, когда большие объекты не могут быть выделены, необходимо заранее запустить полный сборщик мусора.
- 2) Сборщик CMS очень чувствителен к ресурсам процессора. В параллельной фазе, хотя это и не приведет к паузе пользователя, это приведет к замедлению работы приложения, поскольку оно занимает часть потока, и общая пропускная способность будет снижена.
- 3) Сборщик CMS не может обрабатывать плавающий мусор. Возможен сбой «сбой параллельного режима», ведущий к другому полному сборщику мусора. На этапе одновременной маркировки, поскольку рабочие потоки программы и потоки сборки мусора выполняются одновременно или перекрестно, если на этапе параллельной маркировки создаются новые объекты мусора, CMS не сможет пометить эти объекты мусора, которые в конечном итоге приведет к этим вновь сгенерированным объектам мусора.Объекты мусора не собираются вовремя, поэтому ранее несобранное пространство памяти может быть освобождено только при выполнении следующего GC.
настройки параметров
- A XX: +UseConcMarkSweepGc Вручную укажите использование сборщика CMS для выполнения задач высвобождения памяти.
- ➢После включения этого параметра автоматически включается XX: +UseParNewGc. А именно: ParNew (для области Young) +CMS (для области 0ld) + Комбинация Serial 0ld.
- One XX: CMS1niatingOccupanyFraction устанавливает пороговое значение для использования памяти кучи.По достижении порогового значения начинается переработка.
- Значение по умолчанию для JDK5 и предыдущих версий — 68, то есть, когда использование пространства старого возраста достигает 68, будет выполнено восстановление CMS. Значение по умолчанию для JDK6 5 и выше — 92.
- ➢Если рост памяти медленный, вы можете установить немного большее значение.Большее пороговое значение может эффективно снизить частоту срабатывания CMS, а уменьшение количества перезапусков может значительно повысить производительность приложения. И наоборот, если использование памяти приложением быстро растет, этот порог следует понизить, чтобы избежать частых срабатываний последовательного коллектора старого поколения. Таким образом, этот параметр может эффективно сократить количество выполнений полного GC.
- Один XX: +UseCMSCompactAtFullCollection используется для указания того, что FullCollection Сожмите пространство памяти после GC, чтобы избежать фрагментации памяти. Однако, поскольку процесс сжатия памяти не может выполняться одновременно, проблема заключается в том, что время паузы становится больше.
- One XX: CMSFullGCsBeforeCompaction устанавливает, сколько раз выполняется полная сборка мусора для сжатия пространства памяти.
- One XX: ParallelCMSThreads Установите количество потоков CMS.
- Количество потоков, запущенных CMS по умолчанию, равно (ParallelGCThreads+3) / 4, ParallelGCThreads — это количество потоков для параллельного сборщика молодого поколения. Когда ресурсы ЦП ограничены, производительность приложения может быть очень низкой на этапе сборки мусора из-за влияния потока сборщика CM.
резюме:
В HotSpot так много сборщиков мусора, что, если кто спросит, Serial GC,
В чем разница между Parallel GC и Concurrent Mark Sweep GC?
Запомните следующие пароли:
Если вы хотите свести к минимуму использование памяти и издержки параллелизма, выберите Serial GC;
Если вы хотите максимизировать пропускную способность вашего приложения, выберите Parallel GC;
Если вы хотите свести к минимуму прерывания или паузы GC, выберите CMS GC.
Изменения CMS в последующих версиях JDK
- Новое в JDK9: CMS помечен как устаревший (JEP291)
- Если вы используете параметр XX: +UseConcMarkSweepGC для включения сборщика CMS для виртуальной машины HotSpot JDK 9 и выше, пользователь получит предупреждающее сообщение о том, что CMS будет заброшен в будущем.
- Новое в JDK14: удаление сборщика мусора CMS (JEP363).
- Удален сборщик мусора CMS.Если вы используете XX: +UseConcMarkSweepGC в JDK14, JVM не сообщит об ошибке, просто выдаст предупреждающее сообщение, но не выйдет. JVM автоматически отступит и запустит JVM в режиме GC по умолчанию.
G1 Recycler: региональное поколение
Почему мы выпускаем Garbage First (G1) GC, когда у нас уже есть предыдущие сильные GC?
Причина в том, что бизнес, которым занимается приложение, становится все больше и сложнее, а пользователей становится все больше и больше, без GC невозможно гарантировать нормальную работу приложения, а GC STW часто не успевает за фактический спрос, поэтому он будет продолжать работать.Попробуйте оптимизировать GC. Сборщик мусора G1 (Garbage-First) — это новый сборщик мусора, представленный после обновления Java74, и на сегодняшний день это одно из самых передовых достижений в разработке технологии сбора мусора.
В то же время, чтобы адаптироваться к расширяющейся сейчас памяти и увеличивающемуся количеству процессоров, время паузы дополнительно сокращается, учитывая при этом хорошую пропускную способность.
==Официальная цель, установленная для G1, состоит в том, чтобы получить максимально возможную пропускную способность с контролируемой задержкой, поэтому он берет на себя большую ответственность и ожидание «полнофункционального сборщика»==
Почему это называется Garbage First (G1)?
- Поскольку G1 является параллельным сборщиком, он делит динамическую память на множество несвязанных областей (физически прерывистый). Используйте разные регионы для представления Эдема, региона выживших 0, региона выживших 1, старости и т. д.
- Сборщик мусора G1 систематически избегает полной сборки мусора всей кучи Java. G1 отслеживает каждый регион Значение накопления мусора внутри (количество места, полученное при переработке, и значение опыта времени, необходимого для переработки), список приоритетов поддерживается в фоновом режиме, и Регион с наибольшим значением предпочтительно перерабатывается в соответствии с разрешенным время сбора каждый раз.
- Так как целью этого метода является сбор наибольшего количества мусора в регионе (Region), мы даем G1 имя: Garbage First (Сначала Мусор).
- G1 (Garbage-First) — сборщик мусора для серверных приложений, ориентирован в основном на машины, оснащенные многоядерными процессорами и большим объемом памяти, с высокой вероятностью выдерживает время паузы GC, а также обладает высокой производительностью. пропускные характеристики.
- Официально включенный в JDK1.7, логотип Experimental был удален.Это сборщик мусора по умолчанию после JDK 9, заменяющий сборщик CMS и комбинацию Parallel + Parallel 0ld. Официально называется Oracle «полнофункциональным сборщиком мусора».
- Между тем, CMS была помечена как устаревшая в JDK 9. В jdk8 нет сборщика мусора по умолчанию, для включения необходимо использовать XX: +UseG1GC.
Преимущество
По сравнению с другими сборщиками GC, G1 использует новый алгоритм разбиения, который характеризуется следующим:
- Параллелизм и параллелизм
- ➢Параллелизм: в течение периода восстановления G1 несколько потоков Gc могут работать одновременно, эффективно используя многоядерные вычислительные мощности. В этот момент пользовательский поток STW
- ➢ Параллелизм: G1 имеет возможность выполняться попеременно с приложением, а часть работы может выполняться одновременно с приложением, поэтому в целом приложение не будет полностью заблокировано на протяжении всего этапа рециркуляции.
- Коллекция поколений
- ➢ С точки зрения поколения, G1 по-прежнему является сборщиком мусора поколений.Он будет различать молодое поколение и старое поколение, а у молодого поколения по-прежнему есть область Эдема и область Выжившего. Однако, с точки зрения структуры кучи, она не требует, чтобы вся область Эдема, молодое поколение или старое поколение были непрерывными, а также не настаивает на фиксированном размере и фиксированном количестве.
- ➢ Разделите пространство кучи на несколько регионов (Regions), эти регионы содержат логические молодые и старые поколения.
- ➢ В отличие от предыдущих сборщиков учитывает как молодое, так и старое поколение. По сравнению с другими коллекционерами либо работайте в молодом поколении, либо работайте в старом поколении;
- пространственная интеграция
- ➢CMS: алгоритм «отметка для очистки», фрагментация памяти, дефрагментация после нескольких раз Gc
- ➢G1 делит память на регионы. Восстановление памяти основано на регионе как базовой единице.Существует алгоритм репликации между регионами, но фактически его можно рассматривать как алгоритм Mark-Compact в целом.Оба алгоритма позволяют избежать фрагментации памяти. Эта функция удобна для программы, которая работает в течение длительного времени, и следующая сборка мусора не будет запускаться заранее, поскольку при выделении больших объектов невозможно найти непрерывное пространство памяти. Преимущество G1 более очевидно, особенно когда куча Java очень велика.
- Предсказуемая модель времени паузы (т. е. мягкое в реальном времени мягкое в реальном времени)
Это еще одно важное преимущество G1 перед CMS.В дополнение к сокращению пауз, G1 также может установить предсказуемую модель времени паузы, позволяя пользователям явно указывать временной сегмент длиной M миллисекунд, который будет использоваться при сборке мусора. N миллисекунд.
- ➢ Из-за разделения G1 может выбрать только часть области для восстановления памяти, что сужает область восстановления, поэтому возникновение глобальной паузы также можно лучше контролировать.
- ➢G1 отслеживает величину накопления мусора в каждом Регионе (размер пространства, полученного при переработке, равен и значение опыта времени, необходимого для восстановления), поддерживать список приоритетов в фоновом режиме и каждый раз отдавать приоритет восстановлению области с наибольшим значением в соответствии с разрешенным временем сбора. Гарантируется, что коллектор G1 может получить максимально возможную эффективность сбора за ограниченное время.
- ➢ По сравнению с CMSGC, G1, возможно, не сможет добиться задержки и паузы CMS в лучшем случае, но намного лучше в худшем случае.
недостаток
- По сравнению с CMS G1 не имеет всесторонних и подавляющих преимуществ. Например, в запущенном процессе пользовательской программы G1 выше, чем CMS, с точки зрения использования памяти (Footprint) для сборки мусора и дополнительной нагрузки при выполнении (перегрузки) во время работы программы.
- Судя по опыту, производительность CMS в приложениях с небольшим объемом памяти, скорее всего, будет выше, чем у G1, в то время как у G1 есть свои преимущества в приложениях с большим объемом памяти. Точка баланса находится между 6 и 8GB.
настройки параметров
- One XX: +UseG1GC Вручную укажите использование сборщика G1 для выполнения задач высвобождения памяти.
- One XX: G1HeapRegionSize Установите размер каждого региона. Значение представляет собой степень 2, а диапазон составляет 1 МБ. Между 32 МБ цель состоит в том, чтобы выделить около 2048 регионов на основе наименьшего размера кучи Java. По умолчанию используется 1/2000 памяти кучи.
- One XX: MaxGCPauseMillis устанавливает индикатор ожидаемого максимального времени паузы Gc (JVM сделает все возможное, чтобы достичь его, но это не гарантируется). Значение по умолчанию — 200 мс.
- A xX: ParallelGCThread Устанавливает значение количества рабочих потоков sTw. Установить до 8
- A XX: ConcGCThreads Установите количество потоков, помеченных одновременно. Задайте для n примерно 1/4 количества параллельных потоков сборки мусора (ParallelGCThreads).
- One XX: InitiatingHeapOccupancyPercent Задает порог занятости кучи Java, который запускает параллельные циклы сборки мусора. Если это значение превышено, срабатывает GC. Значение по умолчанию — 45.
Общие этапы работы коллектора G1
Принцип разработки G1 заключается в упрощении настройки производительности JVM.Для завершения настройки разработчикам требуется всего три простых шага:
- Шаг 1. Включите сборщик мусора G1.
- Шаг 2: Установите максимальную память кучи
- Шаг 3: Установите максимальное время паузы
В G1 предусмотрено три режима сборки мусора: YoungGC, Mixed GC и Full GC, которые запускаются при разных условиях.
Применимая сцена
- Серверно-ориентированные приложения для машин с большим объемом памяти и несколькими процессорами. (Он плохо работает с кучами нормального размера. Сюрприз)
- Основное приложение — это приложение, которое требует низкой задержки GC и имеет большую кучу для предоставления решения;
- Например, когда размер кучи составляет около 6 ГБ или больше, предсказуемое время паузы может быть менее 0,5 секунды; (G1 гарантирует, что время паузы при каждой сборке мусора не будет возникать путем инкрементной очистки только части области, а не всей области в момент времени). время слишком долго).
- Используется для замены сборщика CMS в JDK1.5;
Использование G1 может быть лучше, чем CMS, в следующих ситуациях:
①Более 50% кучи Java занято активными данными;
② Частота выделения объектов или частота хронологического продвижения сильно различаются;
③Время паузы ГХ слишком велико (больше 0,5–1 секунды). - В сборщике мусора HotSpot, кроме G1, другие сборщики мусора используют встроенное выполнение потока JVM. Многопоточная работа GC, в то время как GC G1 может использовать поток приложения для выполнения работы GC, работающей в фоновом режиме, то есть, когда скорость обработки потока GC JVM низкая, система вызовет поток приложения, чтобы помочь ускорить процесс сбора мусора.
Область раздела, округленная до нуля
При использовании сборщика G1 вся куча Java разделяется примерно на 2048 независимых блоков региона одинакового размера Размер каждого блока региона зависит от фактического размера пространства кучи, а общий размер контролируется в диапазоне от 1 МБ до 32 МБ. и составляет 2 степени N, а именно 1 МБ, 2 МБ, 4 МБ, 8 МБ, 1 6 МБ, 32 МБ. через
XX: параметр G1HeapRegionSize. Все регионы имеют одинаковый размер и не меняются в течение срока службы JVM.
Хотя понятия нового поколения и старого поколения все еще сохраняются, новое поколение и старое поколение больше не изолированы физически, они представляют собой совокупность части Региона (которая не обязательно должна быть непрерывной). Логическая непрерывность достигается за счет динамического выделения регионов.
- Регион может принадлежать к областям памяти Eden, Survivor или 0ld/Tenured. Но регион может принадлежать только одной роли. E на рисунке указывает, что регион принадлежит к области памяти Eden, s указывает, что он принадлежит к области памяти Survivor, а 0 указывает, что он принадлежит к области памяти 0ld. Пробелы на рисунке обозначают неиспользуемое пространство памяти.
- Сборщик мусора G1 также добавляет новую область памяти, называемую областью памяти Humongous, как показано в блоке H. В основном используется для хранения больших объектов, если регионов больше 1,5, то они размещаются в формате H.
- Причина установки H:
- Для больших объектов в куче по умолчанию будет напрямую выделяться старый возраст, но если это недолговечный большой объект, это окажет негативное влияние на сборщик мусора. Чтобы решить эту проблему, G1 разделяет Humongous область, которая используется для хранения больших предметов. Если область H не может содержать большой объект, то G1 будет искать непрерывную область H для сохранения. Чтобы иметь возможность находить последовательные области H, иногда необходимо запустить полный сборщик мусора. Большая часть поведения G1 рассматривает область H как часть старого поколения.
Процесс сборки мусора сборщиком G1
Процесс сборки мусора G1 GC в основном включает следующие три шага:
- Молодой ГК (Молодой ГК)
- Процесс одновременной оценки старости (одновременная оценка)
- Смешанное восстановление (Mixed GC)
- (Однопоточный, эксклюзивный, высокоинтенсивный полный сборщик мусора продолжает существовать, если это необходимо. Он обеспечивает механизм защиты от сбоев при оценке сборщика мусора, сбор грубой силы.)
По часовой стрелке: молодой сборщик мусора один > молодой сборщик мусора + одновременная отметка один > Смешанный порядок сборки мусора для сборки мусора. - Приложение выделяет память и запускает процесс сбора молодого поколения, когда область Эдема молодого поколения исчерпана; этап сбора молодого поколения G1 представляет собой параллельный эксклюзивный сборщик. В период сбора данных молодого поколения G1 GC приостанавливает все потоки приложений и запускает многопоточность для выполнения сбора данных молодого поколения. Затем переместите уцелевший объект из интервала молодого поколения в интервал оставшегося в живых или старый интервал, или могут быть задействованы оба интервала.
- Когда использование памяти кучи достигает определенного значения (по умолчанию 45%), запускается процесс параллельной маркировки старого поколения.
- Немедленно отметьте «Готово». Немедленно начните процесс смешанной переработки. На период смешанного сбора G1 GC перемещает уцелевшие объекты из старого ареала в свободный ареал, и эти свободные ареалы становятся частью старого поколения. В отличие от молодого поколения, сборщик старого поколения G1 отличается от других сборщиков мусора.Сборщику старого поколения G1 не нужно собирать все старое поколение.Ему нужно только сканировать/перерабатывать небольшую часть региона старого поколения с определенной скоростью. время. При этом регион старшего поколения осваивается вместе с молодым поколением.
- Например: веб-сервер, максимальная память кучи процесса Java составляет 4G, и он отвечает на 1500 запросов в минуту, и каждые 45 секунд будет заново выделяться около 2G памяти. G1 будет перерабатывать молодое поколение каждые 45 секунд, а коэффициент использования всей кучи будет достигать 45 каждые 31 ч. Начнется параллельный процесс маркировки старого поколения, и после завершения маркировки начнется от четырех до пяти смешанных коллекций.
Наборы памяти и барьеры записи
- Проблема, связанная с тем, что на объект ссылаются разные регионы (проблема ссылки на поколение)
- Регион не может быть изолирован, и на объекты в регионе могут ссылаться объекты в любом другом регионе.При оценке выживания объекта нужно ли сканировать всю кучу Java для обеспечения точности?
- В сборщиках других поколений тоже есть такие проблемы (причем G1 более заметен)
- Переработка нового поколения также должна одновременно сканировать старое поколение?
- Это снизит эффективность MinorGC;
- ·Решение:
- ➢ Независимо от G1 или сборщиков других поколений, JVM использует RememberedSet, чтобы избежать глобального сканирования:
- ➢Каждый регион имеет соответствующий запоминаемый набор;
- ➢Каждый раз, когда записываются данные опорного типа, будет создан барьер записи для временного прерывания операции; .
- ➢ Затем проверьте, находится ли записываемый объект, на который указывает ссылка, в другом регионе, отличном от данных ссылочного типа (другие сборщики: проверьте, ссылается ли объект старого поколения на объект нового поколения);
- ➢ Если отличается, запишите соответствующую справочную информацию в запомненный набор, соответствующий региону, где ссылка указывает на объект через CardTable;
- ➢ Когда выполняется сборка мусора, в диапазон перечисления корневого узла GC добавляется запомненный набор, который может гарантировать, что не будет выполняться глобальное сканирование и не будет пропусков.
Подробное объяснение процесса переработки G1
1. ГК молодого поколения
- Когда JVM запускается, G1 сначала подготавливает область Eden, и программа постоянно создает объекты в области Eden во время выполнения процесса.Когда пространство Eden будет исчерпано, G1 запустит процесс сборки мусора молодого поколения.
- Сборщик мусора молодого поколения будет перерабатывать только область Эдема и область выживших.
- Во время YGC сначала G1 останавливает выполнение приложения (Stop-The-World), G1 создает набор сбора (Collection Set), который относится к набору сегментов памяти, которые необходимо переработать. Процесс переработки включает в себя молодое поколение всех сегментов памяти в области Эдема и области Выживших.
- Затем запустите процесс переработки следующим образом:
-
Первый этап, сканирование корня.
Корень относится к объекту, на который указывает статическая переменная, локальная переменная в цепочке выполняемых вызовов методов и т. д. Корневая ссылка вместе с внешними ссылками, записанными RSet, служит точкой входа для сканирования живых объектов. -
Второй этап, обновление RSet.
Обработайте карты в очереди грязных карт (см. примечания), обновите RSet. После завершения этой фазы RSet может точно отражать ссылки старого поколения на объекты в том сегменте памяти, где он находится.- очередь грязных карт: для оператора присваивания ссылок приложения object.field=object JVM будет выполнять специальные операции до и после постановки в очередь карты, которая содержит информацию о ссылках на объекты в очереди грязных карт. Когда молодое поколение перерабатывается, G1 против грязной карты Все карточки в Очереди обрабатываются для обновления набора RSet, чтобы убедиться, что набор RSet точно отражает эталонную взаимосвязь в режиме реального времени. Так почему бы не обновить RSet непосредственно в операторе присваивания ссылки? Это нужно для производительности.Обработка RSet требует синхронизации потоков, что будет стоить дорого, а производительность при использовании очередей будет намного лучше.
-
Третий этап, обработка RSet.
Идентифицируйте объекты в Эдеме, на которые указывают объекты старого поколения, и эти заостренные объекты в Эдеме считаются живыми объектами. -
Четвертый этап, копирование объекта.
На этом этапе происходит обход дерева объектов, и уцелевшие объекты в сегменте памяти области Эдема будут скопированы в пустой сегмент памяти в области Уцелевший.Если возраст объектов, уцелевших в сегменте памяти области Уцелевший не достигает порога, возраст будет увеличен на 1, чтобы достичь порога, будет скопирован в пустой сегмент памяти в области 01d. Если пространства Survivor недостаточно, некоторые данные в пространстве Eden будут напрямую перемещены в пространство старого поколения. -
Пятый этап, работа со ссылками.
Обработка ссылок Soft, Weak, Phantom, Final, JNI Weak и т. д. В итоге данные в пространстве Эдема пусты, сборщик мусора перестает работать, а объекты в целевой памяти хранятся непрерывно без фрагментации, поэтому в процессе копирования можно добиться эффекта сортировки памяти и уменьшить фрагментацию.
-
Первый этап, сканирование корня.
2. Параллельный процесс оценки
- Начальная фаза маркировки: пометьте объекты, которые напрямую доступны из корневого узла. Этот этап называется STW и запускает следующее молодое поколение GC.
- Сканирование корневой области (сканирование корневой области): G1 GC сканирует объекты области старого поколения, непосредственно доступные в области Survivor, и помечает объекты, на которые ссылаются. Этот процесс должен быть выполнен перед молодым GC.
- Параллельная маркировка. Параллельная маркировка (и выполнение приложения) выполняется для всей кучи, что может быть прервано молодым сборщиком мусора. Если во время фазы параллельной маркировки все объекты в объекте области будут признаны мусором, область будет немедленно утилизирована. При этом в процессе параллельной маркировки рассчитывается живучесть объектов каждого региона (доля выживших объектов в регионе).
- Remarking (Ремарка): По мере продолжения приложения необходимо исправить последний результат маркировки. Это STW. G1 использует более быстрый алгоритм начального снимка, чем CMS: моментальный снимок в начале (SATB).
- Эксклюзивная очистка (очистка, STW): Рассчитайте уцелевшие объекты и коэффициенты восстановления GC в каждой области и отсортируйте их, чтобы определить области, которые можно смешивать и перерабатывать. Подготовьтесь к следующему этапу. Это STW.
- ➢ Этот этап на самом деле не выполняет сборку мусора.
- Параллельная фаза очистки: определение и очистка полностью свободных областей.
3. Смешанная переработка
Когда все больше и больше объектов перемещается в старый регион старого поколения, чтобы избежать исчерпания памяти кучи, виртуальная машина запускает смешанный сборщик мусора, а именно Mixed GC.Этот алгоритм не является 0ldGC.В дополнение к переработке весь Молодой регион, а также Часть 0ldRegion будет переработана. Обратите внимание: это часть старого поколения, а не все из старого поколения. Вы можете выбрать, какие 0ldRegions собирать, чтобы контролировать трудоемкую сборку мусора. Также обратите внимание, что смешанный сборщик мусора не является полноценным сборщиком мусора.
- После того, как параллельная маркировка заканчивается, 100% сегменты памяти старого поколения освобождаются, и вычисляются частично мусорные сегменты памяти. По умолчанию эти старые сегменты памяти будут освобождены 8 раз (можно установить с помощью XX: G1MixedGCCountTarget).
- Коллекция смешанной коллекции (набор коллекций), включающая одну восьмую сегмента памяти старого поколения, сегмент памяти области Эдема, сегмент памяти области выжившего. Алгоритм смешанного сбора точно такой же, как у молодого поколения, за исключением того, что сегментов памяти старого поколения собирается больше. Чтобы узнать о конкретном процессе, см. выше процесс переработки молодого поколения.
- Поскольку сегменты памяти в старом поколении по умолчанию освобождаются 8 раз, G1 будет отдавать приоритет освобождению сегментов памяти с большим количеством мусора. Чем выше доля мусора в сегменте памяти, тем быстрее он будет переработан. И есть порог, определяющий, будет ли освобожден сегмент памяти, xX: G1MixedGCLiveThresholdPercent, значение по умолчанию — 65%, что означает, что мусор составляет 65% сегмента памяти, прежде чем он может быть освобожден. Если доля мусора слишком низкая, значит, доля уцелевших объектов высока, и для копирования потребуется больше времени.
- Смешанную переработку необязательно выполнять 8 раз. Существует порог Xx:G1HeapWastePercent, значение по умолчанию 10%, что означает, что 10% пространства во всей памяти кучи разрешено тратить впустую, а это означает, что если будет обнаружено, что мусор, который может быть утилизирован, составляет меньше 10% памяти кучи, она больше не будет использоваться.Сделайте смешанную переработку. Потому что сборка мусора займет много времени, а восстановленная память очень мала.
4. Full GC
Первоначальное намерение G1 — избежать возникновения полного GC. Однако, если вышеуказанный метод не работает должным образом, G1 остановит выполнение приложения (Stop-The-World) и будет использовать однопоточный алгоритм восстановления памяти для сборки мусора, производительность будет очень низкой, и приложение время паузы будет очень долгим.
Чтобы избежать возникновения полного GC, его необходимо отрегулировать после его возникновения. Когда будет полная сборка мусора? Например, если память кучи слишком мала, когда у G1 нет свободных сегментов памяти при копировании живых объектов, она вернется к полной gc.Эта ситуация может быть решена путем увеличения памяти.
Причин G1Full GC может быть две:
- 1. Недостаточно места для хранения продвинутого объекта во время Эвакуации;
- 2. Пространство исчерпано до завершения параллельной обработки.
Пополнить
Из официальной информации, раскрытой Oracle, можно узнать, что фаза восстановления (Эвакуация) на самом деле предназначена для выполнения одновременно с пользовательской программой, но это сделать сложнее, учитывая, что G1 восстанавливает только часть Региона, время паузы контролируется пользователем, поэтому его не нужно срочно реализовывать, но он решил поместить эту функцию в сборщик мусора с малой задержкой (т.е. ZGC), который появился после G1. Кроме того, учитывая, что G1 предназначен не только для низкой задержки, приостановка пользовательских потоков может значительно повысить эффективность сборки мусора.Для обеспечения пропускной способности выбрана схема реализации полной приостановки пользовательских потоков.
Предложения по оптимизации
- размер молодого поколения
- ➢Избегайте использования Xmn или XX:NewRatio и других связанных параметров для явной установки размера молодого поколения ➢Фиксация размера молодого поколения переопределит целевое время паузы
- Не будьте слишком строги к целям тайм-аута
- Целевая пропускная способность для G1 GC составляет 90 % времени приложения и 10 % времени сборки мусора.
- При оценке пропускной способности G1 GC целевое время паузы не должно быть слишком строгим. Цель слишком строгая Вы готовы нести дополнительные накладные расходы на сборку мусора, что напрямую влияет на пропускную способность.
Сводка по сборщику мусора
Начиная с JDK 1.8, существует 7 различных сборщиков мусора. Каждый сборщик мусора имеет разные характеристики, поэтому при его использовании вам нужно выбрать другой сборщик мусора в зависимости от конкретной ситуации.
Реализации виртуальных машин разных производителей и разных версий сильно отличаются. Все сборщики и комбинации (подключения) виртуальной машины HotSpot после JDK7/8, как показано ниже:
- 1. Между двумя коллекторами есть соединение, указывающее на то, что их можно использовать вместе: Серийный/Серийный 0ld, Серийный/CMS, ParNew/Серийный 0ld, ParNew/CMS, Параллельная уборка/Серийный 01d, Параллельная уборка/Параллельная 0ld, G1;
- 2. Serial 0ld используется в качестве плана резервного копирования на случай сбоя «Сбой параллельного режима» в CMS.
- 3. (красная пунктирная линия) Из-за стоимости обслуживания и тестирования совместимости Serial+CMS, Две комбинации ParNew+Serial 0ld объявлены устаревшими (JEP 173), и поддержка этих комбинаций полностью объявлена устаревшей в JDK 9 (JEP214), т. е. удалена.
- 4. (зеленая пунктирная линия) JDK 14: устаревшая комбинация ParallelScavenge и Serial0ld GC (JEP 366)
- 5. (голубая пунктирная линия) JDK 14: удалить сборщик мусора CMS (JEP 363) Стадия разработки ГК: Последовательный => Параллельный => CMS => G1 => ZGC
Как выбрать сборщик мусора
- Конфигурация сборщика мусора Java является важным выбором для оптимизации JVM Выбор подходящего сборщика мусора может значительно повысить производительность JVM.
- Как выбрать сборщик мусора?
- 1. Расставьте приоритеты в размере кучи, чтобы позволить JVM работать адаптивно.
- 2. Если объем памяти меньше 100 МБ, используйте последовательный коллектор.
- 3. Если это одноядерная одномашинная программа, и время паузы не требуется, серийный сборщик
- 4. Если имеется несколько ЦП, требуется высокая пропускная способность, а время паузы может превышать 1 секунду, выберите параллелизм или собственный выбор JVM.
- 5. Если он многопроцессорный и требует мало времени паузы, он должен реагировать быстро (например, задержка не может превышать 1 секунду, как в интернет-приложениях) и использовать параллельные сборщики.
- Официальная рекомендация G1, высокая производительность. Сейчас интернет-проекты, в основном, используют G1.
- Наконец, нам нужно уточнить один момент:
- 1. Нет лучшего собирателя, и нет всемогущего собирателя;
- 2. Тюнинг всегда под конкретные сценарии и конкретные нужды, и универсального сборщика не бывает
Анализ журнала сборщика мусора
Читая журнал сборщика мусора, мы можем понять стратегию распределения и утилизации памяти виртуальной машины Java. Список параметров для выделения памяти и сборки мусора
- One XX: +PrintGC выводит журнал Gc. Похоже на: a подробный: gc
- One XX: +PrintGCDetails выводит подробный журнал сборщика мусора
- One XX: +PrintGCTimeStamps Отметка времени вывода GC (в виде эталонного времени)
- a XX: +PrintGCDateStamps выводит отметку времени GC (в виде даты, например 2013-05-04T21:53:59.234+0800)
- One XX: +PrintHeapAtGC распечатывает информацию о куче до и после GC
- Выходной путь Xloggc: ../logs/gc.log к файлу журнала.
+PrintGC
- Журнал открытия сборщика мусора: подробный: gc
- Это покажет только общие изменения кучи GC следующим образом:
[GC (Allocation Failure) 80832K一>19298K(227840K),0.0084018 secs]
[GC (Metadata GC Threshold) 109499K一>21465K (228352K),0.0184066 secs]
[Full GC (Metadata GC Threshold) 21 465K一>16716K (201728K),0.0619261 secs ]
- Разбор параметров:
GC、Full GC: GC的类型,GC只在新生代上进行,Full GC包括永生代,新生代, 老年代。
Allocation Failure: GC发生的原因。
80832K一> 19298K:堆在GC前的大小和GC后的大小。
228840k:现在的堆大小。
0.0084018 secs: GC持续的时间。
PrintGCDetails
- Включить журнал GC:一verbose:gc一 XX: +PrintGCDetaiis
- Введите следующую информацию:
[GC (Allocation Failure) [ PSYoungGen: 70640K一> 10116K(141312K) ] 80541K一>20017K (227328K),0.0172573 secs] [Times: user=0.03 sys=0.00, real=0.02 secs ]
[GC (Metadata GC Threshold) [PSYoungGen:98859K一>8154K(142336K) ] 108760K一>21261K (228352K),
0.0151573 secs] [Times: user=0.00 sys=0.01, real=0.02 secs]
[Full GC (Metadata GC Threshold) [PSYoungGen: 8154K一>0K(142336K) ] [ParOldGen: 13107K一>16809K(62464K) ] 21261K一>16809K (204800K),[Metaspace: 20599K一>20599K (1067008K) ],0.0639732 secs]
[Times: user=0.14 sys=0.00, real=0.06 secs]
- Разбор параметров:
GC,Full FC:同样是GC的类型
Allocation Failure: GC原因
PSYoungGen:使用了Parallel Scavenge并行垃圾收集器的新生代GC前后大小的变化
ParOldGen:使用了Parallel Old并行垃圾收集器的老年代Gc前后大小的变化
Metaspace: 元数据区GC前后大小的变化,JDK1.8中引入了 元数据区以替代永久代
xxx secs : 指Gc花费的时间
Times: user: 指的是垃圾收集器花费的所有CPU时间,sys: 花费在等待系统调用或系统事件的时间, real :GC从开始到结束的时间,包括其他进程占用时间片的实际时间。
PrintGCTimeStamps
- Откройте журнал GC:
一verbose:gc 一XX: +PrintGCDetails 一XX:+PrintGCTimeStamps 一 XX: +PrintGCDateStamps
- Введите следующую информацию:
2019一09一24T22:15:24.518+0800:3.287: [GC(Allocation Failure) [ PSYoungGen: 1361 62K一>5113K(136192K) ] 141425K一>17632K (222208K) ,0.0248249 secs] [Times: user=0.05sys=0.00, real=0.03 secs ]
2019一09一24T22:15:25.559+0800:4.329: [ GC(Metadata GC Threshold)[PSYoungGen:97578K一>10068K(274944K) ] 110096K一>22658K (360960K),0.0094071 secs]
[Times: user=0. 00sys=0.00, real=0. 01 secs]
2019一09一24T22:15:25.569+0800:4.338: [Full GC (Metadata GC Threshold)[ PSYoungGen:10068K一>0K(274944K) ] [ ParoldGen: 12590K一>13564K (56320K) ] 22658K一>13564K (331264K) ,
[Metaspace: 20590K一>20590K(1067008K)], 0. 0494875 secs]
[Times: user=0.17 sys=0. 02,real=0.05 secs ]
Описание: Принесите дату и время
Дополнительные инструкции
- "[GC" и "[Full GC" указывают на тип паузы в этой сборке мусора. Если стоит "Full", это указывает на то, что в GC произошла "StopThe World"
- Имя нового поколения, использующего серийный коллектор, — Новое поколение по умолчанию, поэтому на дисплее отображается «[DefNew».
- При использовании коллектора ParNew имя нового поколения станет «[ParNew», что означает «Параллельное новое поколение».
- Имя нового поколения, использующего сборщик Parallel Scavenge, — «【PSYoungGen».
- Коллекция старого поколения такая же, как у нового поколения, и название также определяется коллекционером.
- При использовании сборщика G1 он будет отображаться как "мусорная куча".
- Ошибка распределения Это показывает, что на этот раз причиной GC является то, что молодому поколению не хватает места для хранения новых данных.
- [PSYoungGen: 5986K->696K (8704K)] 5986K->704K (9216K) В скобках: размер молодой генерации до переработки ГК, размер после переработки, (общая численность молодой генерации) За скобками: размер молодой и старой генераций до сбора ГК, размер после сбора, (сумма размеров молодой и старой генераций)
- user представляет время восстановления в пользовательском режиме, время восстановления sys в режиме ядра и фактическое время rea. Сумма времени может превышать реальное время из-за многоядерности
Minor GC
Full GC
пример
/**
* 在jdk7 和 jdk8中分别执行
* -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+UseSerialGC
*/
public class GCLogTest1 {
private static final int _1MB = 1024 * 1024;
public static void testAllocation() {
byte[] allocation1, allocation2, allocation3, allocation4;
allocation1 = new byte[2 * _1MB];
allocation2 = new byte[2 * _1MB];
allocation3 = new byte[2 * _1MB];
allocation4 = new byte[4 * _1MB];
}
public static void main(String[] agrs) {
testAllocation();
}
}
Использование инструментов анализа логов
Вы можете использовать некоторые инструменты для анализа этих журналов gc.
К часто используемым инструментам анализа журналов относятся: GCViewer, GCEasy, GCHisto, GCLogViewer, Hpjmeter, мусорный кот и т. д.
Новые разработки в сборщиках мусора
Сборщик мусора все еще находится в стадии быстрой разработки, и текущая опция по умолчанию G1 GC постоянно совершенствуется. Многие недостатки, о которых мы изначально думали, такие как последовательный полный сборщик мусора, неэффективность сканирования таблицы карт и т. д., были значительно улучшены. Например, После JDK 10 Fu1l GC работает параллельно, и во многих сценариях его производительность немного выше, чем у параллельной реализации Full GC для Parallel GC.
Даже последовательный сборщик мусора, хотя он относительно стар, его простой дизайн и реализация не могут быть устаревшими Его собственные накладные расходы, будь то накладные расходы на структуры данных, связанные с сборщиком мусора, или накладные расходы потоков, очень малы, поэтому с облачными вычислениями рост Serial GC нашел новый этап в новых сценариях приложений, таких как Serverless.
К сожалению, CMS GC был помечен как устаревший в JDK9 и удален в JDK14, хотя он по-прежнему имеет очень большую группу пользователей из-за теоретических недостатков в его алгоритме.
Новые функции в JDK11
- JEP318: Эпсилон: бесполезный мусор Сборщик (сборщик мусора Epsilon, сборщик "No-Op") http://openidk.java.net/ieps/318
- JEP333: ZGC: масштабируемый сборщик мусора с низкой задержкой (Экспериментальная) (ZGC: Масштабируемый параллельный коллектор с малой задержкой, на экспериментальной стадии)
Shenandoah GC для Open JDK12
- Сборщик G1 уже несколько лет используется по умолчанию.
- Мы также увидели введение двух новых коллекторов:
ZGC (в JDK11) и Shenandoah (открытый JDK12).
- ➢Основная особенность: малое время паузы
Сборщик мусора Shenandoah для Open JDK12: сборщик мусора с малым временем паузы (экспериментальный)
- Шенандоа, несомненно, самый одинокий из многих GC. Это первый сборщик мусора HotSpot, разработанный не командой под руководством корпорации Oracle. Неизбежно, они будут исключены из правительства. Например, Oracle, который утверждает, что между OpenJDK и OracleJDK нет никакой разницы, по-прежнему отказывается поддерживать Shenandoah в OracleJDK12.
- Сборщик мусора Shenandoah изначально был реализацией PauselessGC, исследовательского проекта сборщика мусора, проводимого RedHat, целью которого было достижение низких требований к паузе для освобождения памяти на JVM. Внес вклад в OpenJDK в 2014 году.
- Команда Red Hat R&D Shenandoah объявила, что время паузы сборщика мусора Shenandoah не зависит от размера кучи, а это означает, что независимо от того, установлена ли куча на 200 МБ или 200 ГБ, 99,9% целей могут ограничить время паузы мусора. коллекции до менее десяти миллисекунд. Однако фактическая производительность использования будет зависеть от фактического размера рабочей кучи и рабочей нагрузки.
- Это данные статьи, опубликованной RedHat в 2016 году. Содержание теста заключается в использовании Es для индексации 200 ГБ данных Википедии. Из результатов:
- Время паузы действительно является качественным скачком по сравнению с некоторыми другими сборщиками, но оно не достигло цели контроля максимального времени паузы в пределах десяти миллисекунд.
- Произошло заметное падение пропускной способности, а общее время выполнения было самым продолжительным среди всех сборщиков тестов.
- Слабость Shenandoah GC: падение производительности при высокой нагрузке.
- Сильные стороны Shenandoah GC: низкая задержка.
Революционный ZGC
Ссылка на официальный сайт
Цель ZGC очень похожа на Shenandoah: при минимально возможном влиянии на пропускную способность он может обеспечить низкую задержку, которая может ограничить время паузы сборки мусора менее чем десятью миллисекундами при любом размере кучи памяти.
В книге «Углубленное понимание виртуальной машины Java» ZGC определяется следующим образом: Сборщик ZGC представляет собой схему памяти на основе региона (временно) без генерации, с использованием таких технологий, как барьеры чтения, цветные указатели и множественное сопоставление памяти с достижения Одновременный алгоритм сжатия меток с малой задержкой в качестве основной цели сборщика мусора.
Рабочий процесс ZGC можно разделить на 4 этапа: одновременная маркировка - одновременное перераспределение подготовки - одновременное перераспределение - одновременное переназначение и т.д.
ZGC выполняется одновременно почти везде, за исключением начальной отметки sTW. Так что время паузы почти потрачено на начальную отметку, реальное время этой части очень мало.
Данные испытаний показаны на рисунке:
сравнение недостатков
Сравнение преимуществ
В сильном тесте ZGC на время паузы он безжалостно увеличил разрыв между Parallel и G1 на два порядка. Независимо от средней паузы, 958 пауз, 998 пауз, 99,98 пауз или максимального времени паузы, ZGC может легко контролировать его в течение 10 миллисекунд.
Новые возможности JDK14
JEP 364: приложение ZGC на macOS
JEP 365: ZGC для WindowsДо JDK14 ZGC поддерживался только в Linux.
- Хотя многие пользователи ZGC используют среду, подобную Linux, в Windows и macOS людям также требуется ZGC для разработки, развертывания и тестирования. Многие настольные приложения также могут извлечь выгоду из ZGC. Поэтому функция ZGC была портирована на Windows и macOs.
- Теперь zGC также можно использовать на Mac или Windows, например: axx: +UnlockExperimentalVMOptions axx: +UseZGC .
Другие сборщики мусора: AliGC
AliGC основан на алгоритме G1, разработанном командой Alibaba JVM, и ориентирован на сценарий приложения LargeHeap. Контраст в указанной сцене:Конечно, другие производители также предоставляют различные уникальные реализации сборщика мусора, такие как хорошо известный сборщик мусора с малой задержкой, Zing (Woo Woo.info Q.com/articles/Azi…)
Код обучения JVM и примечания (обновляются один за другим...)
【Код】
GitHub.com/wills звонит…
【Примечания】
Введение в JVM_01
Подсистема загрузки классов JVM_02
Область данных времени выполнения JVM_03 1- [счетчик программ + стек виртуальной машины + стек собственных методов]
Интерфейс собственного метода JVM_04
Область данных среды выполнения JVM_05 с 2 кучами
Область данных среды выполнения JVM_06 Область 3 методов
JVM_07 Область данных среды выполнения 4 — структура памяти экземпляра объекта и позиционирование доступа + прямая память
Механизм выполнения JVM_08 (механизм выполнения)
JVM_09 Строковый постоянный пул StringTable
JVM_10 Сборка мусора 1-Обзор + связанные алгоритмы
JVM_11 Сборка мусора 2 — Понятия, связанные со сборкой мусора
JVM_12 Сборка мусора 3 — сборщик мусора