简体   繁体   English

JVM G1GC的混合gc没有收集太多旧区域

[英]JVM G1GC's mixed gc not collecting much old regions

My server is using 1.8.0_92 on CentOS 6.7, GC param is '-Xms16g -Xmx16g -XX:+UseG1GC'. 我的服务器在CentOS 6.7上使用1.8.0_92,GC参数是'-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. 所以默认的InitiatingHeapOccupancyPercent是45,G1HeapWastePercent是5,而G1MixedGCLiveThresholdPercent是85.我的服务器的混合GC从7.2GB开始,但它越来越少,最后老一代保持大于7.2GB,所以它总是尝试做并发标记。 Finally all heap are exhausted and full GC occurred. 最后所有堆都耗尽并且发生了完整的GC。 After full GC, old gen used is under 500MB. 完全GC后,使用的旧版本低于500MB。

老一代

I'm curious why my mixed GC can't collect more, looks like live data is not so much... 我很好奇为什么我的混合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... 我曾尝试打印g1相关信息,并发现许多消息如下,看起来我的旧版本包含很多实时数据,但为什么完整的GC可以收集这么多......

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 %

Below log is the result of modifying InitiatingHeapOccupancyPercent to 15(start concurrent mark at 2.4GB) to speed up. 以下日志是将InitiatingHeapOccupancyPercent修改为15(启动并发标记为2.4GB)以加快速度的结果。

### 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

EDIT: 编辑:

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,它仍然可以减少到4xx MB,所以看起来我的旧版有更多的数据可以收集。

在此输入图像描述

before full gc, the mixed gc log is 在完全gc之前,混合的gc日志是

 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]

EDIT: 2016/12/11 编辑: 2016/12/11

I have dumped the heap from another machine with -Xmx4G . 我用-Xmx4G从另一台机器上转储了堆。

I used lettuce as my redis client, and it has tracking featured using LatencyUtils. 我使用莴苣作为我的redis客户端,它使用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 ). 它使LatencyStats(其中包含一些具有近3000个元素的long[] )实例每10分钟被弱化一次(默认情况下,发布后的重置延迟为真, https://github.com/mp911de/lettuce/wiki/Command-Latency-Metrics )。 So it will make lots of weak reference of LatencyStats after long time. 所以它会在很长一段时间后对LatencyStats进行大量的弱引用。

Before Full GC. 在Full GC之前。 afterFullGc

afterFullGc

afterFullGc

After Full GC. 完全GC后。 afterFullGc

Currently I don't need tracking from lettuce, so just disable it and it doesn't have full GC anymore. 目前我不需要从生菜跟踪,所以只需禁用它,它就不再有完整的GC了。 But not sure why mixed gc doesn't clear them. 但不确定为什么混合gc不会清除它们。

well, you didnt mentioned all arguments you set, but 好吧,你没有提到你设定的所有论点,但是

you could try to set 你可以尝试设置

-XX:+ScavengeBeforeFullGC

and you should also think about your Object s lifecycle. 你还应该考虑你的Object的生命周期。 how long do your applications Object s live and what size are the Object s. 多长时间做你的应用程序Object小号生活,什么大小的Object秒。

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)

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) 默认值Xms和Xmx设置为32gb - > old gen = 16gb和new gen 16gb - > eden 14gb - >幸存者2gb(有两个,每个大小为1gb)

eden contains all Object s that are instantiated by new Object . 伊甸包含所有Object由实例化小号new Object

one survivor (to-survivor) is always empty. 一名幸存者(幸存者)总是空着的。 the other ones (from-survivor) contains Object s that survived a minor gc 其他的(来自幸存者)包含在较小的gc中存活的Object

surviving Object s from eden and from from-survivor go into to-survivor at minor gc 幸存的来自伊甸园的Object和来自幸存者的Object进入未成年人的幸存者

if the standard-size of 1gb of this 'default-configuration' exceeds, Object s go into old-gen 如果这个'default-configuration'的1gb的标准大小超过,则Object进入old-gen

if it does not exceed, after 15 minor gc's ( -XX:MaxTenuringThreshold s default value), Object s go into old-gen 如果它没有超过15个次要gc( -XX:MaxTenuringThreshold的默认值),则Object进入旧版本

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 通过调整这些值,总是要记住,老一代必须与新一代一样大或大,导致一个gc可以导致整个新一代进入老一代

Edit 编辑

a timeline of your first "old gen: used" picture would be helpful 你的第一张“老一代:用过的”图片的时间表会有所帮助

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 请记住,在老一代不超过之前不需要做一个完整的gc - 一个完整的gc导致整个“世界”停止一段时间

in this particular case, i would say you could 在这种特殊情况下,我会说你可以

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

and you will get an old and new gen, each sized 4gb, 你会得到一个新老一代,每个4gb,

eden at size of 2gb, 伊甸园大小为2gb,

two survivors, each sized 1gb, 两名幸存者,每人1gb,

and aproximately 50 minor gc's, before Object s go into old gen Object进入旧世代之前,大约有50个小gc

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

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