G1GC 年老代提交的堆随着时间的推移而增加(生产时大约 5 到 6 天),但年老代使用的堆没有。 Eden 和survivor 堆被迫减少到最小值(总堆的5%),因此垃圾收集越来越频繁。应用程序在开始时缓存一个大对象图,然后在其整个运行生命周期中使用其他时间/使用受限的缓存。它具有相当高的对象创建率,但除了缓存对象外,并没有将其中的大部分提升到老年代。
我已经通过 gceasy.io 运行了 GC 日志,您可以看到内存的上述行为:
https://gceasy.io/my-gc-report.jsp?p=c2hhcmVkLzIwMjAvMDUvMTEvLS1nY2xvZy50YXIuZ3otLTExLTMwLTE5&channel=WEB .
日志:
https://drive.google.com/open?id=176X-Lku4D3DGCCdTiB0_z545N8n0tfKc
本次运行的 Grafana 内存指标 https://snapshot.raintank.io/dashboard/snapshot/k6g3ljG7cQUEJM7jA4c5tBK1dsUnzabd
运行结束时的堆转储(负载已移除大约一个小时,这是一个 500M 的 gz 文件):https://drive.google.com/open?id=14ghzIVnpelInSyQBhCwUwM5VkuOjX13-
我们似乎没有高大的对象创建。服务器有 12G 的 RAM,堆有 6G。
虚拟机:
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)
内核:3.10.0-1062.12.1.el7.x86_64
最佳答案
一般来说,committed
是正常的。内存值高于 used
. promise 开始于 -Xms
并且可以上升到-Xmx
,但是 committed
不是 resident
. Resident
这里的意思是在 RAM 中,而 used = resident + swapped pages
.所以used
可以波动很大,而committed
没有那么多,至少,我是这样理解的。
GC 从值 -Xms
开始作为初始提交的内存,并且会缓慢增长(当然最多可达 -Xmx
)。现在我已经做了这个介绍,我真的认为这对你的应用程序没有任何意义。让我解释。
据我从您提供的日志中看到,一切都在预期中(并且正常)。 G1
MaxGCPauseMillis = 200ms
有一个默认值这表示允许您的应用程序停止多少(在快乐路径场景中)。根据这个值,G1
做出正确的决定来重新调整区域大小。根据您的日志,Eden
周围空间270MB
(平均)最多收集到 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
我可以发现(除了您进行堆转储时的那个)。
关于java - G1GC 老一代提交的堆不断增长,使用的是恒定的 - 导致伊甸园饥饿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61730183/