繁体   English   中英

G1GC Old Gen committed heap 不断增长,used is constant - leads to Eden starvation

[英]G1GC Old Gen committed heap keeps growing, used is constant - leads to Eden starvation

G1GC old generation committed heap 随着时间的推移(大约 5 到 6 天生产)而上升,但 old generation used heap 不会。 Eden 和 survivor 堆被迫减少到最小值(总堆的 5%),因此垃圾收集越来越频繁。 该应用程序在开始时缓存一个大的 object 图,然后在其整个运行生命周期中进行其他时间/使用有限的缓存。 它具有相当高的 object 创建率,但除了缓存的对象外,并没有将其中的大部分提升到老年代。

I have run the GC log through gceasy.io and you can see the above behaviour of the memory: https://gceasy.io/my-gc-report.jsp?p=c2hhcmVkLzIwMjAvMDUvMTEvLS1nY2xvZy50YXIuZ3otLTExLTMwLTE5&channel=WEB .

gclog: https://drive.google.com/open?id=176X-Lku4D3DGCCdTiB0_z545N8n0tfKc

此运行的 Grafana memory 指标https://snapshot.raintank.io/dashboard/snapshot/k6g3ljG7cQUEJM7jA4c5tBK1dsUnzabd

运行结束时的堆转储(负载已移除约一个小时,这是一个 500M gz 文件): https://drive.google.com/open?id=14ghzIVnpelInSyQBhCwUwM5VkuOjX13-

object 好像我们没有很高的创作水平。 服务器有 12G RAM,堆有 6G。

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 release 7.7.1908 (Core)

Kernel:3.10.0-1062.12.1.el7.x86_64

一般来说, committed memory 值高于used是正常的。 已提交以-Xms开头,并且可以 go 到-Xmx ,但已committed不是resident的。 这里的Resident意味着在 RAM 中,而used = resident + swapped pages 所以used可以波动很大,而committed没有那么多,至少,我是这样理解的。

GC 以-Xms的值作为初始提交的 memory 开始,并且会慢慢增长(当然会达到-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 (除了你进行堆转储时的那个)。

从您的 GC 日志中,下面是 GCViewer 的外观

GC 日志显示 Ref Proc 是 High GC Time 的瓶颈 所以建议尝试 -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 Proc 上
  2. 逐渐减少 -XX:InitiatingHeapOccupancyPercent(默认为 45)以查看混合 GC 是否可以更早发生并帮助改善行为
  3. 增加-XX:G1NewSizePercent 避免年轻代减少太小

希望可以帮助它

GC 查看器用户界面

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM