Улучшение производительности сборщика мусора G1 в Java VM

G1 предназначен для обеспечения хорошей общей производительности без необходимости указывать дополнительные опции. Однако существуют случаи, когда эвристика по умолчанию или конфигурации по умолчанию для них дают неоптимальные результаты. В этом разделе приведены некоторые рекомендации по диагностике и улучшению в этих случаях. В этом руководстве описаны только те возможности, которые G1 предоставляет для повышения производительности сборщика мусора в выбранной метрике, если задано установленное приложение. В каждом конкретном случае оптимизация на уровне приложений может быть более эффективной, чем попытка настроить виртуальную машину для повышения производительности, например, за счет избежания некоторых проблемных ситуаций с помощью менее долговечных объектов в целом.

В целях диагностики G1 обеспечивает полное ведение журнала. Хорошим началом является использование опции -Xlog:gc*=debug, а затем, при необходимости, уточнение выходных данных. Журнал предоставляет подробный обзор во время и за пределами паузы о деятельности по сбору мусора. Это включает в себя тип сбора и разбивку времени, затраченного на определенные этапы паузы.

В следующих подразделах рассматриваются некоторые распространенные проблемы с производительностью.

Наблюдение за полными сборками мусора (Full GC)

Полная сборка мусора в куче (Full GC) часто занимает очень много времени. Полные GC, вызванные слишком высокой загрузкой кучи в старом поколении, можно обнаружить, найдя в журнале слова Pause Full (Allocation Failure). Полному сборщику мусора обычно предшествуют сборки мусора, которые сталкиваются с ошибкой эвакуации, обозначенной исчерпанными метками в пространстве.

Причина, по которой возникает Full GC, заключается в том, что приложение выделяет слишком много объектов, которые не могут быть восстановлены достаточно быстро. Часто одновременная маркировка не может быть завершена вовремя, чтобы начать этап освоения пространства. Вероятность столкновения с Full GC может быть усугублена выделением множества огромных объектов. Из-за того, как эти объекты расположены в G1, они могут занимать гораздо больше памяти, чем ожидалось.

Цель должна состоять в том, чтобы одновременная маркировка выполнялась вовремя. Это может быть достигнуто либо уменьшением скорости выделения в старом поколении, либо предоставлением конкурентной маркировке больше времени для завершения.

G1 дает вам несколько вариантов, чтобы лучше справиться с этой ситуацией:

  • Вы можете определить количество областей, занятых огромными объектами в куче Java, используя ведение журнала gc+heap=info. Y в строках "Humongous region: X->Y" отображает количество областей, занятых огромными объектами. Если это число велико по сравнению с количеством старых областей, лучшим вариантом будет попытаться уменьшить это количество объектов. Этого можно добиться, увеличив размер региона с помощью параметра -XX:G1HeapRegionSize. Текущий выбранный размер области кучи печатается в начале журнала.
  • Увеличьте размер кучи Java. Это, как правило, увеличивает количество времени, необходимое для маркировки.
  • Увеличьте число конкурентных потоков разметки, явно указав -XX:ConcGCThreads.
  • Заставьте G1 начать маркировку раньше. G1 автоматически определяет пороговое значение процента инициализации кучи (IHOP) на основе более раннего поведения приложения. Если поведение приложения изменяется, эти прогнозы могут быть неверными. Есть два варианта: уменьшить целевую занятость для того, когда начинать восстановление пространства, увеличив буфер, используемый в адаптивном вычислении IHOP, изменив -XX:G1ReservePercent; или отключите адаптивный расчет IHOP, установив его вручную с помощью -XX:-G1UseAdaptiveIHOP и -XX:InitiatingHeapOccupancyPercent.

Другие причины, кроме ошибки распределения для полного GC, обычно указывают на то, что приложение или какой-либо внешний инструмент вызывает полный сбор кучи. Если причиной является System.gc(), и нет способа изменить источники приложения, эффект полных сборщиков мусора можно смягчить с помощью -XX:+ExplicitGCInvokesConcurrent или позволить виртуальной машине полностью игнорировать их, задав -XX:+DisableExplicitGC. Внешние инструменты могут по-прежнему использовать Full GC; они могут быть удалены только без их запроса.

Фрагментация огромных объектов

Полная сборка мусора (Full GC) может произойти до того, как вся память кучи Java будет исчерпана из-за необходимости найти для них непрерывный набор областей. Потенциальные опции в этом случае увеличивают размер области кучи с помощью опции -XX:G1HeapRegionSize, чтобы уменьшить количество огромных объектов или увеличить размер кучи. В крайних случаях может не хватить непрерывного пространства, доступного для G1, чтобы выделить объект, даже если доступная память указывает иное. Это приведет к выходу виртуальной машины, если этот Full GC не сможет восстановить достаточно непрерывного пространства. В результате нет других вариантов, кроме как уменьшить количество огромных распределений объектов, как упомянуто ранее, или увеличить кучу.


Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки