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




Проблема может быть связана с другими аспектами конфигурации сборки мусора G1 или шаблонами использования памяти приложения. Вот дополнительные стратегии и корректировки, которые вы можете попробовать, чтобы уменьшить длинные паузы GC:
-XX:G1HeapRegionSize=4M
-XX:MaxGCPauseMillis=200
-XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=60
-XX:ParallelGCThreads=8 -XX:ConcGCThreads=4
-XX:+UseStringDeduplication
Дальнейшие дела
Если это утечка памяти в куче. Действия по диагностике Запустите приложение с уменьшенным размером кучи и наблюдайте за поведением. Регулярно записывайте дампы кучи, особенно если вы замечаете длительные паузы в сборе мусора. Проанализируйте дампы кучи с помощью таких инструментов, как JProfiler, чтобы выявить любые объекты, которые должны были быть удалены сборщиком мусора, но все еще находятся в памяти. Изучите пути кода, которые приводят к сохранению этих объектов.
Я заметил, что размер кучи почти не изменился. Куча: 484,6M(5120,0M) -> 338,4M(5120,0M), означает ли это, что некоторые объекты не вызывают длительных пауз?
Что заставляет вас думать, что это проблема GC? Это также может быть утечка памяти. Это также может привести к длительному времени сборки мусора. А если это утечка памяти, настройка параметров JVM ее не исправит.