Spring MVC G1 GC Old Gen committed heap不断增长,used is constant -导致Eden饥饿

yb3bgrhw  于 10个月前  发布在  Spring
关注(0)|答案(2)|浏览(199)

G1 GC老一代提交的堆会随着时间的推移而增加(在生产环境中大约5到6天),但老一代使用的堆不会。Eden和幸存者堆被强制减少到最小值(总堆的5%),因此垃圾收集越来越频繁。应用程序在开始时缓存一个大的对象图,然后在其整个运行生存期内进行其他时间/使用受限的缓存。它具有相当高的对象创建率,但除了缓存的对象外,并没有将其提升到老一代。
我已经通过www.example.com运行了GC日志gceasy.io,您可以看到内存的上述行为:https://gceasy.io/my-gc-report.jsp?p=c2hhcmVkLzIwMjAvMDUvMTEvLS1nY2xvZy50YXIuZ3otLTExLTMwLTE5&channel=WEB的数据。
gclog:https://drive.google.com/open?id=176X-Lku4D3DGCCdTiB0_z545N8n0tfKc
此运行https://snapshot.raintank.io/dashboard/snapshot/k6g3ljG7cQUEJM7jA4c5tBK1dsUnzabd的Grafana内存度量
运行结束时的堆转储(已移除负载约一小时,这是一个500 M gz文件):https://drive.google.com/open?id=14ghzIVnpelInSyQBhCwUwM5VkuOjX13-
我们似乎没有高的巨大物体创造。服务器有12 G的RAM,而堆有6 G。
jvm:

openjdk version "1.8.0_242"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_242-b08)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.242-b08, mixed mode)

字符串
jvm标志:

-XX:CICompilerCount=4
-XX:ConcGCThreads=2
-XX:G1HeapRegionSize=2097152
-XX:GCLogFileSize=104857600
-XX:InitialHeapSize=6442450944
-XX:InitialRAMPercentage=50.000000
-XX:+ManagementServer
-XX:MarkStackSize=4194304
-XX:MaxHeapSize=6442450944
-XX:MaxNewSize=3865051136
-XX:MaxRAMPercentage=50.000000
-XX:MinHeapDeltaBytes=2097152
-XX:MinRAMPercentage=50.000000
-XX:NumberOfGCLogFiles=10
-XX:+PrintGC
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+UseCompressedClassPointers
-XX:+UseCompressedOops
-XX:+UseG1GC
-XX:+UseGCLogFileRotation


我们使用CentOS在openshift上运行:CentOS Linux发行版7.7.1908(核心)
内核:3.10.0-1062.12.1.el7.x86_64

j2qf4p5b

j2qf4p5b1#

一般情况下,committed内存值高于used是正常的。Committed以-Xms开始,可以上升到-Xmx,但committed * 不是 * residentResident在这里表示 * 在RAM中 *,而used = resident + swapped pages。所以used可以波动很大,而committed没有那么大,至少,这是我的理解。
GC以-Xms的值作为初始提交的内存开始,并将缓慢增长(当然最多到-Xmx)。现在我已经做了这个介绍,我真的不认为这对您的应用程序有任何意义。听我解释
据我所知,从您提供的日志中,一切都很正常(正常)。G1有一个MaxGCPauseMillis = 200ms的默认值,它表示你的应用程序被允许停止的程度(在快乐路径场景中)。根据这个值,G1会做出正确的决定来重新调整区域的大小。根据您的日志,大约270MB(平均)的Eden空间被收集到0.2s中。只是一个随机的例子从你的日志:

[Eden: 280.0M ....
Times: user=0.49 sys=0.00, real=0.18 secs
2020-05-04T02:43:01.742+0000: 315128.451: [GC pause (G1 Evacuation Pause) (young), 0.1740299 secs]

字符串
所以这正是你间接要求的对我来说,你的应用程序是完全好的,那些GC pause (G1 Evacuation Pause)需要尽可能多的配置。顺便说一句,你觉得自己幸运吗?但是在整个日志文件中,我找不到一个Full GC(除了获取堆转储时的那个)。

pxy2qtax

pxy2qtax2#

下面是GC日志在GCViewer中的显示
GC日志显示Ref Proc是高GC时间的瓶颈,因此建议尝试-XX:+ParallelRefProcEnabled,看看它是否有帮助

[Ref Proc: 151.3 ms]
  [Ref Proc: 147.2 ms]
  [Ref Proc: 146.6 ms]
  [Ref Proc: 183.0 ms]
  [Ref Proc: 156.4 ms]
  [Ref Proc: 152.7 ms]
  [Ref Proc: 143.7 ms]
  [Ref Proc: 137.8 ms]
  [Ref Proc: 194.8 ms]
  [Ref Proc: 153.3 ms]
  [Ref Proc: 153.6 ms]

字符串
还有一些其他的几件事可以尝试改进:
1.打开-XX:PrintReferenceGC以获取在Ref过程上花费的更多详细时间
1.逐渐减少-XX:InitiatingHeapOccupancyPercent(默认值为45),以查看混合GC是否可以更早发生,并对行为有所帮助
1.增加-XX:G1 NewSizePercent以避免年轻一代减少太小
希望能帮上忙
x1c 0d1x的数据

相关问题