G1 GC требует много времени для копирования объектов

Мое приложение представляет собой типичное веб-приложение Java, Java 8, использующее G1 GC. Я столкнулся с проблемой GC. В течение 10 минут после запуска приложения (когда старое поколение постепенно увеличивается) часто происходит долгий GC, но на этапе стабильной работы этого не происходит. Ниже приведен мой журнал GC:

{Heap before GC invocations=43 (full 0):
 garbage-first heap   total 5242880K, used 496183K [0x00000006a7800000, 0x00000006a7a05000, 0x00000007e7800000)
  region size 2048K, 128 young (262144K), 54 survivors (110592K)
 Metaspace       used 228219K, capacity 255729K, committed 255872K, reserved 1275904K
  class space    used 24456K, capacity 29030K, committed 29056K, reserved 1048576K
2024-06-20T11:44:47.168+0800: 260.143: [GC pause (G1 Evacuation Pause) (young), 9.8956459 secs]
   [Parallel Time: 9891.3 ms, GC Workers: 4]
      [GC Worker Start (ms): Min: 260143.9, Avg: 260145.0, Max: 260147.2, Diff: 3.3]
      [Ext Root Scanning (ms): Min: 5.1, Avg: 8.8, Max: 12.5, Diff: 7.5, Sum: 35.2]
      [Update RS (ms): Min: 0.0, Avg: 12.2, Max: 16.2, Diff: 16.2, Sum: 48.6]
         [Processed Buffers: Min: 0, Avg: 39.2, Max: 69, Diff: 69, Sum: 157]
      [Scan RS (ms): Min: 0.0, Avg: 1.1, Max: 1.9, Diff: 1.8, Sum: 4.4]
      [Code Root Scanning (ms): Min: 0.0, Avg: 4.0, Max: 6.1, Diff: 6.1, Sum: 15.8]
      [Object Copy (ms): Min: 9855.0, Avg: 9863.9, Max: 9884.8, Diff: 29.8, Sum: 39455.6]
      [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
         [Termination Attempts: Min: 1, Avg: 15.8, Max: 23, Diff: 22, Sum: 63]
      [GC Worker Other (ms): Min: 0.1, Avg: 0.1, Max: 0.1, Diff: 0.0, Sum: 0.2]
      [GC Worker Total (ms): Min: 9887.8, Avg: 9890.0, Max: 9891.1, Diff: 3.3, Sum: 39560.0]
      [GC Worker End (ms): Min: 270035.0, Avg: 270035.0, Max: 270035.0, Diff: 0.1]
   [Code Root Fixup: 1.1 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 0.2 ms]
   [Other: 3.0 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 1.1 ms]
      [Ref Enq: 0.0 ms]
      [Redirty Cards: 0.5 ms]
      [Humongous Register: 0.1 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 0.4 ms]
   [Eden: 148.0M(148.0M)->0.0B(234.0M) Survivors: 108.0M->22.0M Heap: 484.6M(5120.0M)->338.4M(5120.0M)]
Heap after GC invocations=44 (full 0):
 garbage-first heap   total 5242880K, used 346567K [0x00000006a7800000, 0x00000006a7a05000, 0x00000007e7800000)
  region size 2048K, 11 young (22528K), 11 survivors (22528K)
 Metaspace       used 228219K, capacity 255729K, committed 255872K, reserved 1275904K
  class space    used 24456K, capacity 29030K, committed 29056K, reserved 1048576K
}
 [Times: user=17.10 sys=0.90, real=9.90 secs] 

Я попробовал увеличить площадь ВЫЖИВШЕГО, но это не сработало. Вот мои параметры JVM:

-Xmx5120m -Xms5120m -XX:MaxMetaspaceSize=400M -XX:MetaspaceSize=400M -XX:+UseG1GC -XX:SurvivorRatio=6 -Dnacos.use.endpoint.parsing.rule=false -Dnacos.use.cloud.namespace.parsing=false -XX:+PrintHeapAtGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -Xloggc:/tmp1/main-gc.log

Что заставляет вас думать, что это проблема GC? Это также может быть утечка памяти. Это также может привести к длительному времени сборки мусора. А если это утечка памяти, настройка параметров JVM ее не исправит.

Stephen C 20.06.2024 11:30

Мое приложение только что было запущено менее 5 минут, а памяти еще много, поэтому я не думаю, что возникла проблема с утечкой памяти images.tuodan.tech/operate/20240620/…

hongyiheng 20.06.2024 13:59

Извините... но мы здесь не читаем по-китайски, поэтому понять эти изображения невозможно.

Stephen C 20.06.2024 16:57
images.tuodan.tech/operate/20240621/…
hongyiheng 21.06.2024 03:50
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
4
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема может быть связана с другими аспектами конфигурации сборки мусора G1 или шаблонами использования памяти приложения. Вот дополнительные стратегии и корректировки, которые вы можете попробовать, чтобы уменьшить длинные паузы GC:

-XX:G1HeapRegionSize=4M
-XX:MaxGCPauseMillis=200
-XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=60
-XX:ParallelGCThreads=8 -XX:ConcGCThreads=4
-XX:+UseStringDeduplication

Дальнейшие дела

  1. Анализ дампа кучи. Собирайте и анализируйте дампы кучи на проблемном этапе, чтобы понять, какие объекты потребляют память. Используйте инструменты профилирования, такие как VisualVM, YourKit или Java Mission Control, для анализа моделей использования памяти и распределения объектов. Мой любимый JProfiler
  2. Мониторинг журналов GC: Постоянно отслеживайте и анализируйте журналы GC, чтобы выявить любые закономерности или конкретные выделения, которые могут вызывать длительные паузы GC. Следите за частыми или длительными паузами при эвакуации G1.
  3. Постепенное увеличение: Если применимо, постепенно увеличивайте размер кучи, чтобы освободить больше места для объектов, что позволит сборщику мусора работать более эффективно.

Если это утечка памяти в куче. Действия по диагностике Запустите приложение с уменьшенным размером кучи и наблюдайте за поведением. Регулярно записывайте дампы кучи, особенно если вы замечаете длительные паузы в сборе мусора. Проанализируйте дампы кучи с помощью таких инструментов, как JProfiler, чтобы выявить любые объекты, которые должны были быть удалены сборщиком мусора, но все еще находятся в памяти. Изучите пути кода, которые приводят к сохранению этих объектов.

Munkh-Erdene Jargal 20.06.2024 11:53

Я заметил, что размер кучи почти не изменился. Куча: 484,6M(5120,0M) -> 338,4M(5120,0M), означает ли это, что некоторые объекты не вызывают длительных пауз?

hongyiheng 20.06.2024 13:16

Другие вопросы по теме