当前位置: 首页 > 知识库问答 >
问题:

G1GC老一辈promise的堆不断增长,经常使用-导致伊甸园饥饿

松俊美
2023-03-14

G1GC老一代提交的堆随着时间的推移而上升(生产时大约5到6天)但老一代使用的堆没有。伊甸园和幸存者堆被迫减少到最低限度(总堆的5%),因此垃圾回收机制,因为越来越频繁。应用程序在一开始就缓存了一个大对象图,然后在整个运行生命周期中拥有其他时间/使用有限的缓存。它具有相当高的对象创建率,但除了缓存的对象之外,并没有向老一代推广其中的很多内容。

我已经通过gceasy运行了GC日志。io,您可以看到内存的上述行为:https://gceasy.io/my-gc-report.jsp?p=c2hhcmVkLzIwMjAvMDUvMTEvLS1nY2xvZy50YXIuZ3otLTExLTMwLTE5

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

Grafana本次运行的内存指标https://snapshot.raintank.io/dashboard/snapshot/k6g3ljG7cQUEJM7jA4c5tBK1dsUnzabd

运行结束时堆转储(负载已经被删除了大约一个小时,这是一个500Mgz文件):https://drive.google.com/open?id=14ghzIVnpelInSyQBhCwUwM5VkuOjX13-

我们似乎没有高质量的物体创造。服务器有12G内存,堆有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上运行:CentOSLinux版本7.7.1908(核心)

内核:3.10.0-1062.12.1。el7。x86_64

共有2个答案

桂玉石
2023-03-14

从您的GC日志中,以下是它在GCViewer中的外观

GC Log显示Ref Proc是高GC时间的瓶颈,因此建议尝试-XX: ParallelRefProcEnable,看看它是否可以提供帮助

  [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: PrintReduce ceGC以获取在Ref Proc上花费的更多详细时间
  2. 减少-XX:逐步启动Heap占用百分比(默认为45),看看混合GC是否可以更早发生并帮助行为
  3. 增加-XX: G1NewSizePercent避免年轻一代减少太少

希望能帮上忙

皮承基
2023-03-14

一般情况下,提交的内存值高于使用的是正常的。提交以-Xms开头,最高可以到-Xmx,但提交的不是驻留驻留这里的意思是在RAM中,而use=驻留交换页面。所以使用的可以波动很大,而提交的没有那么多,至少,这是我对这个的理解。

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暂停(G1疏散暂停)占用的资源与你配置的一样多。顺便说一句,你觉得自己很幸运吗?但在整个日志文件中,我没有发现一个完整的Full GC(除了在进行堆转储时的一个)。

 类似资料:
  • 出于某种原因,G1决定增加提交的旧一代内存(尽管使用的内存没有增加),并减少Eden一代提交的内存(从而减少可用空间)。这似乎导致GC年轻一代的运行激增,并使应用程序在一段时间内没有响应。 我们还可以看到CPU使用率和机器中提交的虚拟内存总量(比物理内存总量还要大)出现峰值。也可能会看到磁盘使用率和swapout/swapin的激增。 我的问题是: G1决定减少Eden的大小并大幅增加老一代的pr

  • 你能回答我一个关于JVM垃圾收集过程的问题吗? 为什么堆被分为伊甸园、幸存者空间和老一代? 当一个年轻的疏散被处理时,通过从根开始的引用访问对象,以找出无法到达的对象。可到达的对象标记为“活动”,不可到达的对象不标记,将被删除。 因此,所有对象都会被考虑,包括旧一代中分配的对象也会被访问并标记是否可以访问。 据我所知,同时回收年轻一代和老一代是非常困难的,因为这两代人位于内存中不同的连续部分。 但

  • 这是来自太空的100%新的伊甸园--一个问题吗? 我的JAVA选项是:-xms10240m-xmx14336m-xx:permsize=192m-xx:maxpermsize=256m-xx:newsize=8192m-xx:maxnewsize=8192m-xx:-disableexplicitgc-xx:+useconcmarksweepgc-xx:cmsinitiatingoccupancy

  • 我正在centos 6上运行java应用程序,使用G1GC运行openjdk版本“1.8.0_232”。我看到堆的总使用量逐渐增加,导致应用程序崩溃。当我对活动对象进行堆转储时,转储大小仅为1.6GB,但我使用的总堆容量为32GB。 用于获取dump:jmap-dump:live、format=b、file=/tmp/dump的命令。hprof 从某个地方读到,jmap dump命令会触发一个完整

  • 在JVM重启之前,java(8)内存容量是否会减少? 我正在使用jstat-gc转储内存信息,下面是两天的快照。与第一个快照相比,第二个快照对SC1和EC的资本金更少。 有人能帮助/解释为什么我看到这种行为吗?这是预期的吗?

  • 我正在用Xamarin开发一个Android应用程序。我在从字流生成图像方面遇到了问题。BitmapFactory(似乎是最流行的解决方案)正在引发巨大的分配问题--Grow堆。