Как я могу настроить G1GC для меньшего объема памяти?
Я экспериментировал с G1GC с Java 8 (Oracle JVM) на одном из моих проектов. Мои флаги GC эффективно:
-Xms64m
-Xmx1024m
-XX:+UseG1GC
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
-Xloggc:/tmp/gc.log
-XX:+PrintAdaptiveSizePolicy
Я наблюдаю, что куча растет намного больше, чем объем живых данных, которые у меня есть. Журналы GC показывают, что я считаю основной причиной:
[G1Ergonomics (Heap Sizing) attempt heap expansion, reason: recent GC overhead higher than threshold after GC, recent GC overhead: 10.17 %, threshold: 10.00 %, uncommitted: 811597824 bytes, calculated expansion amount: 162319564 bytes (20.00 %)]
По сути, мое приложение генерирует много мусора, поэтому доля времени, проведенного в GC, превышает 10%, поэтому эргономика G1 увеличивает размер кучи.
С помощью параллельного коллектора этот порог может быть настроен с -XX:GCTimeRatio
(цель пропускной способности), но из того, что я вижу в документах, нет эквивалентного флага для G1.
Для параллельного сборщика Java SE предоставляет два параметра настройки сборки мусора, которые основаны на достижении определенного поведения приложения: цель максимального времени паузы и цель пропускной способности приложения; см. раздел "Параллельный коллектор". (Эти два параметра недоступны в других сборщиках.) Обратите внимание, что такое поведение не всегда может быть выполнено.
Мой вопрос, кроме снижения максимального размера кучи, как я могу настроить G1GC для меньшего объема памяти?
В журналах нет никаких доказательств того, что я отключаю максимальное время паузы и даже увеличиваю его, что не решает проблему.
Возможно, это вопрос этого вопроса: какой флаг JVM устанавливает порог служебной нагрузки GC, указанный в журнале G1Ergonomics?, но там, похоже, неверный ответ был принят. (Или, возможно, это было правильно только для более старой версии JVM.)
2 ответа
Обзор:
В этой статье Oracle (1) вы можете найти наиболее важные флаги для G1 (включая
-XX:MaxGCPauseMillis
).Этот отчет об ошибке указывает на то, что
GCTimeRatio
Флаг также используется в G1.Пожалуйста, также посмотрите этот связанный вопрос и ответ (2).
Я предполагаю, что вы сможете решить эту проблему, установив
-XX:MaxGCPauseMillis
к более высокому значению, или если вы знаете, что ваше приложение создает много (молодого) мусора, вы можете поиграть с настройками размера молодого поколения. РЕДАКТИРОВАТЬ: ОК, будьте очень осторожны с этим, (1) заявляет: * Размер молодого поколения *: Избегайте явного задания размера молодого поколения с помощью параметра -Xmn или любого другого параметра, например -XX:NewRatio. Фиксирование размера молодого поколения переопределяет цель цели времени паузы.
(1)
Важные значения по умолчанию:
G1 GC - это адаптивный сборщик мусора со значениями по умолчанию, которые позволяют ему работать эффективно без изменений. Вот список важных опций и их значения по умолчанию. Этот список относится к последней версии Java HotSpot VM, сборка 24. Вы можете адаптировать и настроить G1 GC в соответствии с требованиями производительности вашего приложения, введя следующие параметры с измененными настройками в командной строке JVM.
- -XX: G1HeapRegionSize = п
Устанавливает размер области G1. Значение будет иметь степень двойки и может варьироваться от 1 до 32 МБ. Цель состоит в том, чтобы иметь около 2048 регионов на основе минимального размера кучи Java.
- -XX: MaxGCPauseMillis = 200
Устанавливает целевое значение для желаемого максимального времени паузы. Значение по умолчанию составляет 200 миллисекунд. Указанное значение не адаптируется к вашему размеру кучи.
- -XX: G1NewSizePercent = 5
Устанавливает процент кучи для использования в качестве минимального размера для молодого поколения. Значение по умолчанию составляет 5 процентов от вашей кучи Java. Это экспериментальный флаг. Смотрите "Как разблокировать экспериментальные флаги VM" для примера. Этот параметр заменяет параметр -XX:DefaultMinNewGenPercent. Этот параметр недоступен в Java HotSpot VM, сборка 23.
- -XX: G1MaxNewSizePercent = 60
Устанавливает процент от размера кучи, который будет использоваться как максимальный размер для молодого поколения. Значение по умолчанию составляет 60 процентов вашей кучи Java. Это экспериментальный флаг. Смотрите "Как разблокировать экспериментальные флаги VM" для примера. Этот параметр заменяет параметр -XX:DefaultMaxNewGenPercent. Этот параметр недоступен в Java HotSpot VM, сборка 23.
- -XX: ParallelGCThreads = п
Устанавливает значение рабочих потоков STW. Устанавливает значение n в число логических процессоров. Значение n совпадает с числом логических процессоров до значения 8.
Если имеется более восьми логических процессоров, установите значение n равным приблизительно 5/8 логических процессоров. Это работает в большинстве случаев, за исключением больших систем SPARC, где значение n может составлять примерно 5/16 от логических процессоров.
- -XX: ConcGCThreads = п
Устанавливает количество параллельных разметочных нитей. Устанавливает n равным приблизительно 1/4 от числа параллельных потоков сборки мусора (ParallelGCThreads).
- -XX: InitiatingHeapOccupancyPercent = 45
Устанавливает порог занятости кучи Java, который запускает цикл маркировки. Заполнение по умолчанию составляет 45 процентов всей кучи Java.
- -XX: G1MixedGCLiveThresholdPercent = 65
Устанавливает порог занятости для старого региона, который будет включен в цикл смешанного сбора мусора. Заполняемость по умолчанию составляет 65 процентов. Это экспериментальный флаг. Смотрите "Как разблокировать экспериментальные флаги VM" для примера. Этот параметр заменяет параметр -XX:G1OldCSetRegionLiveThresholdPercent. Этот параметр недоступен в Java HotSpot VM, сборка 23.
- -XX: G1HeapWastePercent = 10
Устанавливает процент кучи, которую вы готовы тратить. Виртуальная машина Java HotSpot не запускает цикл смешанного сбора мусора, когда процент извлекаемой памяти меньше, чем процент отходов кучи. По умолчанию это 10 процентов. Этот параметр недоступен в Java HotSpot VM, сборка 23.
- -XX: G1MixedGCCountTarget = 8
Устанавливает целевое число смешанных сборок мусора после цикла маркировки для сбора старых областей с не более чем G1MixedGCLIveThresholdPercent живых данных. По умолчанию используется 8 смешанных сборок мусора. Цель для смешанных коллекций - быть в пределах этого целевого числа. Этот параметр недоступен в Java HotSpot VM, сборка 23.
- -XX: G1OldCSetRegionThresholdPercent = 10
Устанавливает верхний предел на количество старых областей, которые будут собираться во время смешанного цикла сбора мусора. По умолчанию используется 10% кучи Java. Этот параметр недоступен в Java HotSpot VM, сборка 23.
- -XX: G1ReservePercent = 10
Устанавливает процентную долю резервной памяти, которая остается свободной, чтобы снизить риск переполнения пространства. По умолчанию это 10 процентов. Когда вы увеличиваете или уменьшаете процент, не забудьте откорректировать общую кучу Java на ту же величину. Этот параметр недоступен в Java HotSpot VM, сборка 23.
(2)
Я думаю, что recent GC overhead higher than threshold
управляет решениями G1. Вы можете расслабиться, установив -XX:GCTimeRatio=4
, что позволило бы ему занимать 20% циклов ЦП относительно времени приложения для GCing вместо 10%.
Если это слишком много, вы должны либо
Позволить ему использовать больше ядер ЦП - это облегчит достижение целей, связанных с временем паузы, что, в свою очередь, означает, что он может откладывать сборы на более длительный срок, облегчая достижение цели по пропускной способности. да, это означает, что использование большего количества ядер может в целом использовать меньше циклов ЦП.
расслабить время паузы цели, поэтому он должен собирать реже
При дальнейшем исследовании выясняется, что эргономика G1 действительно уважает -XX:GCTimeRatio
несмотря на то, что говорят документы.