JVM G1GC的混合gc不会收集很多旧区域 [英] JVM G1GC's mixed gc not collecting much old regions

查看:174
本文介绍了JVM G1GC的混合gc不会收集很多旧区域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的服务器在CentOS 6.7上使用1.8.0_92,GC参数为'-Xms16g -Xmx16g -XX:+ UseG1GC'.因此,默认的InitiatingHeapOccupancyPercent是45,G1HeapWastePercent是5,G1MixedGCLiveThresholdPercent是85.我的服务器的混合GC从7.2GB开始,但是它的清理越来越少,最后旧的gen保持大于7.2GB,所以它总是尝试做并发标记.最后,所有堆都耗尽了,并且发生了完整的GC.完全GC后,使用的旧gen不足500 MB.

My server is using 1.8.0_92 on CentOS 6.7, GC param is '-Xms16g -Xmx16g -XX:+UseG1GC'. So the default InitiatingHeapOccupancyPercent is 45, G1HeapWastePercent is 5 and G1MixedGCLiveThresholdPercent is 85. My server's mixed GC starts from 7.2GB, but it clean less and less, finally old gen keeps larger than 7.2GB, so it's always try to do concurrent mark. Finally all heap are exhausted and full GC occurred. After full GC, old gen used is under 500MB.

我很好奇为什么我的混合GC无法收集更多的东西,看起来实时数据不是那么多...

I'm curious why my mixed GC can't collect more, looks like live data is not so much...

我尝试打印与g1相关的信息,发现许多如下所示的消息,看起来我的老一代包含很多实时数据,但是为什么完整的GC可以收集到如此多的信息.​​..

I have tried printing g1 related info, and found many messages like below, looks like my old gen contains much live data, but why full GC can collect so much...

G1Ergonomics (Mixed GCs) do not continue mixed GCs, reason: reclaimable percentage not over threshold, candidate old regions: 190 regions, reclaimable: 856223240 bytes (4.98 %),  threshold: 5.00 %

下面的日志是将InitiatingHeapOccupancyPercent修改为15(以2.4GB开始并发标记)以加快速度的结果.

Below log is the result of modifying InitiatingHeapOccupancyPercent to 15(start concurrent mark at 2.4GB) to speed up.

### PHASE Post-Marking
......
### SUMMARY  capacity: 16384.00 MB  used: 2918.42 MB / 17.81 %  prev-live: 2407.92 MB / 14.70 %  next-live: 2395.00 MB / 14.62 %  remset: 56.66 MB  code-roots: 0.91 MB
### PHASE Post-Sorting
....
### SUMMARY  capacity: 1624.00 MB  used: 1624.00 MB / 100.00 %  prev-live: 1123.70 MB / 69.19 %  next-live: 0.00 MB / 0.00 %  remset: 35.90 MB  code-roots: 0.89 MB

我尝试在混合GC后触发完全GC,但它仍可以减少到4xx MB,因此看来我的老一代可以收集更多数据.

I try to trigger full GC after mixed GC, it still can reduce to 4xx MB, so looks like my old gen has more data can be collected.

在gc满之前,混合的gc日志为

before full gc, the mixed gc log is

 32654.979: [G1Ergonomics (Mixed GCs) start mixed GCs, reason: candidate old regions available, candidate old regions: 457 regions, reclaimable: 2956666176 bytes (17.21 %), threshold: 5.00 %], 0.1106810 secs]
 ....
 [Eden: 6680.0M(6680.0M)->0.0B(536.0M) Survivors: 344.0M->280.0M Heap: 14.0G(16.0G)->7606.6M(16.0G)]
 [Times: user=2.31 sys=0.01, real=0.11 secs]
 ...
 [GC pause (G1 Evacuation Pause) (mixed)
 ...
 32656.876: [G1Ergonomics (CSet Construction) finish adding old regions to CSet, reason: old CSet region num reached max, old: 205 regions, max: 205 regions]
 32656.876: [G1Ergonomics (CSet Construction) finish choosing CSet, eden: 67 regions, survivors: 35 regions, old: 205 regions, predicted pause time: 173.84 ms, target pause time: 200.00 ms]
 32656.992: [G1Ergonomics (Mixed GCs) continue mixed GCs, reason: candidate old regions available, candidate old regions: 252 regions, reclaimable: 1321193600 bytes (7.69 %), threshold: 5.00 %]
 [Eden: 536.0M(536.0M)->0.0B(720.0M) Survivors: 280.0M->96.0M Heap: 8142.6M(16.0G)->6029.9M(16.0G)]
 [Times: user=2.49 sys=0.01, real=0.12 secs]
 ...
 [GC pause (G1 Evacuation Pause) (mixed)
 ...
 32659.727: [G1Ergonomics (CSet Construction) finish adding old regions to CSet, reason: reclaimable percentage not over threshold, old: 66 regions, max: 205 regions, reclaimable: 857822432 bytes (4.99 %), threshold: 5.00 %]
 32659.727: [G1Ergonomics (CSet Construction) finish choosing CSet, eden: 90 regions, survivors: 12 regions, old: 66 regions, predicted pause time: 120.51 ms, target pause time: 200.00 ms]
 32659.785: [G1Ergonomics (Mixed GCs) do not continue mixed GCs, reason: reclaimable percentage not over threshold, candidate old regions: 186 regions, reclaimable: 857822432 bytes (4.99 %), threshold: 5.00 %]
 [Eden: 720.0M(720.0M)->0.0B(9064.0M) Survivors: 96.0M->64.0M Heap: 6749.9M(16.0G)->5572.0M(16.0G)]
 [Times: user=1.20 sys=0.00, real=0.06 secs]

2016/12/11

2016/12/11

我已经用-Xmx4G从另一台计算机上转储了堆.

I have dumped the heap from another machine with -Xmx4G.

我用生菜做我的Redis客户,它具有使用LatencyUtils进行跟踪的功能.它使LatencyStats(其中包含一些具有近3000个元素的long[])实例每10分钟被弱引用一次(默认情况下,发布后的重置延迟为true,

I used lettuce as my redis client, and it has tracking featured using LatencyUtils. It make LatencyStats(which contains some long[] with near 3000 elements) instances weak referenced every 10 mins(Reset latencies after publish is true by default, https://github.com/mp911de/lettuce/wiki/Command-Latency-Metrics). So it will make lots of weak reference of LatencyStats after long time.

完整GC之前.

完全GC后.

目前,我不需要从生菜中进行跟踪,因此只需禁用它,它就不再具有完整的GC.但是不确定为什么混合的gc不能清除它们.

Currently I don't need tracking from lettuce, so just disable it and it doesn't have full GC anymore. But not sure why mixed gc doesn't clear them.

推荐答案

好吧,您没有提到您设置的所有参数,但是

well, you didnt mentioned all arguments you set, but

您可以尝试设置

-XX:+ScavengeBeforeFullGC

,您还应该考虑Object的生命周期.您的应用程序Object可以使用多长时间,Object的大小是多少.

and you should also think about your Objects lifecycle. how long do your applications Objects live and what size are the Objects.

考虑一下,看看下面的论点

think about it and take a look at the following arguments

-XX:NewRatio=n              old/new ration (default 2)
-XX:SurvivorRatio=n         eden/survivor ratio (default 8)
-XX:MaxTenuringThreshold=n  number of times, objects are moved from survivor one to survivor two and vice versa before objects are moved to old-gen (default 15)

具有默认值 Xms和Xmx设置为32gb->老一代= 16gb和新一代16gb->伊甸园14gb->幸存者2gb(有两个,每个大小为1gb)

with default values Xms and Xmx are set to 32gb -> old gen = 16gb and new gen 16gb -> eden 14gb -> survivors 2gb (there are two, each of it at the size of 1gb)

eden包含由new Object实例化的所有Object.

eden contains all Objects that are instantiated by new Object.

一个幸存者(至幸存者)始终为空.其他(来自幸存者)包含Object,它们在未成年人gc中幸存了

one survivor (to-survivor) is always empty. the other ones (from-survivor) contains Objects that survived a minor gc

幸存者Object在未成年人gc处进入幸存者

surviving Objects from eden and from from-survivor go into to-survivor at minor gc

如果此默认配置"的标准大小超出了1gb,则Object进入旧版本

if the standard-size of 1gb of this 'default-configuration' exceeds, Objects go into old-gen

如果未超过该值,则在15个次要gc(默认值为-XX:MaxTenuringThreshold)之后,Object进入旧世代

if it does not exceed, after 15 minor gc's (-XX:MaxTenuringThresholds default value), Objects go into old-gen

通过调整这些值,请始终牢记,旧一代必须与新一代一样大或更大,因为gc可以使整个新一代都变成老一代

by tweaking those values, always keep in mind, old-gen has to be as large as or larger than new-gen, cause a gc can cause the whole new-gen to go into old-gen

修改

第一张老一代:二手"照片的时间表会很有帮助

a timeline of your first "old gen: used" picture would be helpful

请记住,在老一代不超过之前,无需做完整的gc-完整的gc会使整个世界"停止一定时间

keep in mind that there is no need to do a full gc until old gen doesn't exceed - a full gc causes the whole "world" to stop for a certain period of time

在这种情况下,我会说你可以

in this particular case, i would say you could

  1. -Xms-Xmx减少到8gb
  2. -XX:SurvivorRatio的值设置/减小为2
  3. -XX:MaxTenuringThreshold设置/增加到50
  1. reduce -Xms and -Xmx to 8gb
  2. set/decrease -XX:SurvivorRatios value to 2
  3. set/increase -XX:MaxTenuringThreshold to 50

您将获得一个新老一代,每个大小为4GB,

and you will get an old and new gen, each sized 4gb,

eden大小为2GB,

eden at size of 2gb,

两个幸存者,每个幸存者大小为1gb,

two survivors, each sized 1gb,

和大约50个未成年人gc,在Object进入老一代之前

and aproximately 50 minor gc's, before Objects go into old gen

这篇关于JVM G1GC的混合gc不会收集很多旧区域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆