G1内存划分G1看起来和CMS比较类似,但是实现上有很大的不同。
传统分代GC将整体内存分为几个大的区域,比如Eden,S0,S1,Tenured等。而G1将内存区域分为了n个不连续的,大小相同的Region,Region具体的大小为1到32M,根据总的内存大小而定,目标是数量不超过2048个。 如下图所示:
G1调优参数
-XX:+UseG1GC : 使用G1回收器。
-XX:G1HeapRegionSize=2m : 指定分区大小(1MB~32MB,且必须是2的幂),默认将整堆划分为2048个分区
-XX:MaxGCPauseMillis = 200 : 设置最大暂停目标。默认为200,G1只会仅最大努力达到这个目标,这个目标值需要结合项目进行调整,时间太短,则可能会引起吞吐下降,同时每次Mixed GC回收的垃圾过少,导致最后垃圾堆积引起Full GC,时间太长,则可能会引起用户体验不佳。
*
-XX:InitiatingHeapOccupancyPercent = 45 : 表示并发开始GC周期的堆使用阈值,当整个堆的使用量达到阈值时,就会开始并发周期。这个参数和CMS一样主要用来防止Mixed GC过程中的并发失败,如果过晚进行并发回收,则可能会因为并发过程中剩余的内存不足以满足用户所树妖的内存,这就会导致G1放弃并发标记,升级为Full GC.这种情况一般都能在GC中看到to-space exhausted字样。
这个参数也不能调的太小,太小会导致一直循环,占用CPU资源。
*
-XX:G1MixedGCCountTarget=8 : 每次Mixed GC回收的老年代内存数量,默认为8,这也是为了解决to-space exhausted的问题,每次Mixed GC多回收一些,老年代空余的内存就会多一些,但是相应的可能会导致暂停时间增加
*
-XX:ConcGCThreads : 每次GC使用的CPU数量, 值不是固定。同样也是为了解决to-space exhausted的问题,使用线程多,则GC便会快一些,代价是用户的CPU时间会被占用。
*
-XX:G1ReservePercent=10%: 假天花板数量,作用是预留10%的空间不使用,留给并发周期过程中当可能会出现to-space exhausted的问题时候使用,防止出现to-space exhausted,预留过多可能会导致内存浪费
*
不要设置年轻代大小:不要使用-Xmn,因为G1是通过需要扩展或缩小年轻代大小,如果设置了年轻代大小,则会导致G1无法使用暂停时间目标。
实战设置G1收集器
jmap -heap pid
最多可以有2048个Region。 对这句话存有疑问, 从结果看默认G1HeapRegionSize是2m, 但是出现了4000个region
修改参数G1HeapRegionSize=4m
region变成了200个了
-Xmx8000m:设置JVM最大可用内存为8000M。
-Xms8000m:设置JVM促使内存为8000m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。