Как запустить коллекцию Old Generation в G1GC - PullRequest
0 голосов
/ 18 апреля 2019

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

При расследовании нескольких случаев этих сбоев существует шаблон, который я определил с точки зрения JVM:

  • до сбоя количество потоков увеличивается до уровня выше нормального
  • перед сбоем обычно нормальный шаблон пилообразного общего использования кучи исчезает, и размер кучи увеличивается без уменьшения
  • до крушения, молодое поколение кучи неизменно низкое и, похоже, не меняет или не увеличивает в использовании
  • до крушения, старое поколение вырастает до размеров, превышающих размеры предыдущих поколений, и, похоже, не очищается и не собирается
  • segfault всегда имеет отношение к активному потоку GC, в частности copy_to_survivor_space

Хотя я не вижу убедительных доказательств возникновения нехватки памяти, я придерживаюсь мнения, что у нас действительно заканчивается свободное пространство для приложения. Если G1GC не может скопировать молодые объекты в оставшееся место до эвакуации или продвижения по службе, кажется, логически следует, что у него не было достаточно места для этого. Анализируя журналы GC, я не вижу ничего общего с огромными объектами, так как не думаю, что они занимают кучу места в куче.

Глядя на профиль памяти, я догадываюсь, что мне нужно уменьшить InitiatingHeapOccupancyPercent до значения, близкого к значению по умолчанию 45, чтобы запустить цикл сбора данных раньше. Мне кажется, особенно учитывая постоянно растущий размер Old Gen, что смешанный / полный GC должен запускаться чаще или, по крайней мере, раньше. Как начать полную / смешанную коллекцию?

Исходя из предоставленной информации, есть ли другие мысли или мнения о том, как я могу быстрее начать сбор? Я неверно истолковываю сообщение segfault и иду по неверному пути? Что еще я могу сделать, чтобы собрать информацию, которая может помочь мне устранить первопричину сбоев?


Detail
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f38aa2655f5, pid=6293, tid=0x00007f3894efe700
#
# JRE version: Java(TM) SE Runtime Environment (8.0_162-b12) (build 1.8.0_162-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.162-b12 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# V  [libjvm.so+0x5c85f5]  G1ParScanThreadState::copy_to_survivor_space(InCSetState, oopDesc*, markOopDesc*)+0x45
#

memory snapshot

Параметры JVM:

-XX:MaxHeapSize=30g
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=512m
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:InitiatingHeapOccupancyPercent=70
-XX:-OmitStackTraceInFastThrow
-XX:+AlwaysPreTouch
-XX:+UseStringDeduplication
-XX:+UseCompressedOops

-Xloggc:/usr/local/company/logs/gc.log
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=10
-XX:GCLogFileSize=100M
-XX:+PrintAdaptiveSizePolicy
-XX:+PrintGCApplicationConcurrentTime
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintGCCause
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintHeapAtGC
-XX:+PrintReferenceGC
-XX:+PrintTenuringDistribution
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/usr/local/company/logs/heapdump_126960.hprof

1 Ответ

1 голос
/ 19 апреля 2019

Я неверно истолковал сообщение о segfault и направился по неверному пути?

Да, heap-OOM никогда не должны приводить к segfault, вместо этого они должны запускать только из ошибок памяти через механизм исключения / сбрасывания. Подпись сбоя указывает либо на ошибку JVM, либо на повреждение кучи, вызванное внешними факторами (собственные библиотеки, загруженные в процесс JVM, повреждение памяти, неправильное использование Unsafe).

Попробуйте обновить JVM и посмотрите, устранена ли причина в более новых версиях. Если это не помогает, попробуйте удалить части вашего приложения, зависимости, java-агенты и т. Д. Или запустить на другом оборудовании.

...