Для InitiatingHeapOccupancyPercent установлено значение 40, но память старого поколения в G1GC превышает 60 процентов. - PullRequest
2 голосов
/ 27 апреля 2020

Я пытаюсь решить проблему, когда объем кучи в моей службе java превышает 90 процентов.

Ниже приведена конфигурация кучи, которую я использую,

-Xms6144m \
                -Xmx6144m \
                -verbose:gc \
               -XX:G1HeapRegionSize=2097152 \
               -XX:+PrintGC \
               -XX:+PrintFlagsFinal \
               -XX:InitiatingHeapOccupancyPercent=40 \
               -XX:NewRatio=2 \
               -XX:+PrintGCDetails \
               -XX:+PrintGCDateStamps \
               -XX:+PrintAdaptiveSizePolicy \
               -XX:+PrintTenuringDistribution \
               -XX:+UseGCLogFileRotation \
               -XX:NumberOfGCLogFiles=10 \
               -XX:GCLogFileSize=50M \
    -XX:+UnlockExperimentalVMOptions \
  -XX:+UseG1GC -XX:+UseStringDeduplication \
  -XX:+UseCGroupMemoryLimitForHeap \
  -XX:+ParallelRefProcEnabled
  -XX:+OptimizeStringConcat
  -XX:MaxRAMFraction=2 \
  -XshowSettings:vm

Проблема в том, что мой старый ген постепенно заполняется, и со временем нижняя точка, к которой идет куча после увеличения G C, мой график выглядит примерно так:

enter image description here

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

1 Ответ

1 голос
/ 09 мая 2020

G1G C в основном предназначен для одной цели, поддерживая отзывчивость вашего приложения:

, пытаясь избежать этой сборки мусора "старого поколения" (постоянных объектов, которые приложение удерживает для Некоторое время, например, из пользовательского сеанса, кеша или какой-то утечки памяти) должно быть выполнено в одном классе c FullG C, где ваше приложение заморожено, а вся куча должна быть очищена (что зависит от количество объектов может занять много времени, например, несколько секунд. Узнайте все об этом здесь , одна цитата из него:

Цель состоит в том, чтобы освободить как можно больше пространства кучи (начиная с тех регионов, которые содержат наиболее пригодное для восстановления пространство) при попытке не превысить цель времени паузы

40%, которые вы установили для: InitiatingHeapOccupancyPercent, относятся к (вся) занятость кучи и обозначение, когда начинать параллельный цикл G C (это должно быть видно в журналах, если не видно: этот связанный вопрос ). запустить параллельный цикл G C, основанный на заполнении всей кучи, а не только одного поколения (не только Old Gen), включая G1, используйте эту опцию. Значение 0 обозначает «делать константу G C циклов». Значение по умолчанию - 45. (Адаптировано из: Oracle® Communications WebRT C Руководство системного администратора Session Controller )

Поэтому возможно, что:

  1. Цикл G C запускается при заполнении кучи 40%, но до его завершения вы достигаете гораздо более высокого уровня (например, 90%), что может быть вполне нормально, если ваше приложение работает
  2. У вас есть какая-то утечка памяти (но по графику трудно понять, не зная приложения и продолжительности его работы или не видя, как оно работает через более длительное время)
  3. Могут быть и другие проблемы, но это Невозможно определить, не имея журналов сбора мусора для анализа, но вы можете обратиться к: статье Моники Беквит о G1G C, например, части о Evacuation Failure

Если вы действительно хотите, чтобы ваше приложение использовало меньше памяти (возможно, за счет некоторой потери в производительности / пропускной способности), вы можете уменьшить MaxHeapSize (но вы должны использовать любой из них). из: MaxRAMFraction или MaxHeapSize (XmX), но не оба).

Или, в зависимости от вашего приложения и требований к производительности, рассмотрите возможность использования совершенно другого JVM / сборщика мусора, например:

...