-XX:+UseG1GC
-XX:InitiatingHeapOccupancyPercent=N这个参数,默认状况下该参数是45
-XX:G1MixedGCCountTarget=N参数能够管制每个混合式周期中回收的Old分区数量,该参数的默认值是8;
-XX:G1HeapRegionSize=N;只有对象大小>=1/2 region,那么这个对象就会被JVM标记为Humongous object。每一个巨型对象是一组间断的region,调配在老年代。 如:如果region为1m,对象大小为600KB,那么残余的空间(1024kb - 600kb)将成为碎片,不在参加调配。须要防止Humongou Obj的产生,应该防止大对象的加载。、-XX:MaxGCPauseMillis=200 – 设置一个指标最大暂停工夫. 这是一个理想化的指标,JVM会尽可能的实现它
-XX:G1ReservePercent=n,默认是10 G1会预留一部分内存,制作一个假天花板,避免to-sapce exhausted。
yang gc:当年老代空间不够
mixed gc:老年代大小占整个堆大小百分比达到该阈值时,会触发一次mixed gc.
full gc:
to-sapce exhausted:老区不够了,这个时候会把young区所有对象不论死活都转成old区对象,而后紧接着一次full gc。G1收集器实现了标记阶段,开始启动混合式垃圾收集,筹备要清理老年代分区,然而老年代分区在垃圾收集器开释出足够的空间之前就曾经被耗尽了。这种失败通常意味着混合式垃圾收集须要更迅速得实现垃圾收集,每次新生代垃圾收集须要解决更多的老年代分区。
Evacuation Failure:是指当G1无奈在堆空间中申请新的分区时,G1便会触发担保机制,执行一次STW式的、单线程的Full GC。Full GC会对整堆做标记革除和压缩,最初将只蕴含纯正的存活对象。参数-XX:G1ReservePercent(默认10%)能够保留空间,来应答降职模式下的异常情况
Metadata GC Threshold:元空间不够,也会触发full gc。
Humongous Allocation:调配巨型对象时在老年代无奈找到足够的间断分区。
Remembered Set:虚拟机发现程序在对Reference类型的数据进行写操作时,会产生一个Write Barrier临时中断写操作,查看Reference援用的对象是否处于不同的Region之中。如果是,便通过Card Table把相干援用信息记录到被援用对象所属的Region的Remembered Set之中。RSet外面记录了援用--就是其余Region中指向本Region中所有对象的所有援用,也就是谁援用了我的对象。
G1 GC每次都会对年老代进行整体收集(全副扫描)。因而young->old和young->young也不须要在RSet中记录。而对于old->young和old->old的跨代对象援用,须要领有RSet。
对于G1进行YGC时的跨代援用,以及进行Mixed GC时的old 间跨region援用,只有到本Region RSet所记录的region中扫描援用了脏card区域的对象,再如法溯源,判断其是否存活存活,进而确定本分区内的对象存活状况。而不须要扫描整个堆了
PLAB( promotion local allocation buffer)。每一个线程在survival space和old space中都一个PLAB。在晋升的时候,能够防止多线程的竞争,从而晋升效率。
CSet(收集汇合)代表每次GC暂停时回收的一系列指标分区。在任意一次收集暂停中,CSet所有分区都会被开释,外部存活的对象都会被转移到调配的闲暇分区中。因而无论是年老代收集,还是混合收集,工作的机制都是统一的。年老代收集CSet只包容年老代分区,而混合收集会通过启发式算法,在老年代候选回收分区中,筛选出回收收益最高的分区增加到CSet中。
候选老年代分区的CSet准入条件,能够通过活跃度阈值-XX:G1MixedGCLiveThresholdPercent(默认85%)进行设置,从而拦挡那些回收开销微小的对象;同时,每次混合收集能够蕴含候选老年代分区,可依据CSet对堆的总大小占比-XX:G1OldCSetRegionThresholdPercent(默认10%)设置数量下限。G1的收集都是依据CSet进行操作的,年老代收集与混合收集没有显著的不同,最大的区别在于两种收集的触发条件。
年老代垃圾回收只会回收Eden区和Survivor区。
YGC时,首先G1进行应用程序的执行(Stop-The-World),G1创立回收集(Collection Set),回收集是指须要被回收的内存分段的汇合,年老代回收过程的回收集蕴含年老代Eden区和Survivor区所有的内存分段。
而后开始如下回收过程:
第一阶段,扫描根。
根是指static变量指向的对象,正在执行的办法调用链条上的局部变量等。跟援用连同RSet记录的内部援用作为扫描存活对象的入口。
第二阶段,更新RSet。
解决dirty card queue(见备注)中的card,更新RSet。此阶段实现后,RSet能够精确的反映老年代对所在的内存分段中对象的援用。
备注:
对于应用程序的援用赋值语句object.field=object,JVM会在之前和之后执行非凡的操作以在dirty card queue中入队一个保留了对象援用信息的card。在年老代回收的时候,G1会对Dirty Card Queue中所有的card进行解决,以更新RSet,保障RSet实时精确的反映援用关系。
那为什么不在援用赋值语句处间接更新RSet呢?这是为了性能的须要,RSet的解决须要线程同步,开销会很大,应用队列性能会好很多
第三阶段,解决RSet。
辨认被老年代对象指向的Eden中的对象,这些被指向的Eden中的对象被认为是存活的对象。
第四阶段,复制对象。
此阶段,对象树被遍历,Eden区内存段中存活的对象会被复制到Survivor区中空的内存分段,Survivor区内存段中存活的对象如果年龄未达阈值,年龄会加1,达到阈值会被复制到Old区中空的内存分段。如果Survivor空间不够,Eden空间的局部数据会间接降职到老年代空间。
第五阶段,解决援用。
解决Soft,Weak,Phantom,Final,JNI Weak 等援用。最终Eden空间的数据为空,GC进行工作,而指标内存中的对象都是间断存储的,没有碎片,所以复制过程能够达到内存整理的成果,缩小碎片。
G1回收过程二: 并发标记过程
- 初始标记阶段: 标记从根节点间接可达的对象。这个阶段是STW的,并且会触发一次年老代GC。
- 根区域扫描(Root Region Scanning): G1 GC扫描survivor区间接可达的老年代区域对象,并标记被援用的对象。这一过程必须在young GC之前实现。
- 并发标记(Concurrent Marking): 在整个堆中进行并发标记(和应用程序并发执行),此过程可能被young GC中断。在并发标记阶段,若发现区域对象中的所有对象都是垃圾,那这个区域会被立刻回收。同时,并发标记过程中,会计算每个区域的对象活性(区域中存活对象的比例)。
- 再次标记(Remark): 因为应用程序继续进行,须要修改上一次的标记后果。是STW的。G1中采纳了比CMS更快的初始快照法: snapshot-at-the-beginning(SATB)。
- 独占清理(cleanup,STW): 计算各个区域的存活对象和GC回收比例,并进行排序,辨认能够混合回收的区域。为下阶段做铺垫。是STW的。
- 并发清理阶段: 辨认并清理齐全闲暇的区域。
G1回收过程三: 混合回收
当越来越多的对象降职到老年代old region时,为了防止堆内存被耗尽,虚构机会触发一个混合的垃圾收集器,即Mixed GC,该算法并不是一个Old GC,除了回收整个Young Region,还会回收一部分的Old Region。这里须要留神: 是一部分老年代,而不是全副老年代。能够抉择哪些Old Region进行收集,从而能够对垃圾回收的耗时工夫进行管制。也要留神的是Mixed GC并不是Full GC。
并发标记完结当前,老年代中百分百为垃圾的内存分段被回收了,局部为垃圾的内存分段被计算了进去。默认状况下,这些老年代的内存分段会分8次(能够通过-XX:G1MixedGCCountTarget设置)被回收。
混合回收的回收集(Collection Set)包含八分之一的老年代内存分段,Eden区内存分段,Survivor区内存分段。混合回收的算法和年老代回收的算法齐全一样,只是回收集多了老年代的内存分段。具体过程请参考下面的年老代回收过程。
因为老年代中的内存分段默认分8次回收,G1会优先回收垃圾多的内存分段。垃圾占内存分段比例越高,越会被先回收。并且有一个阈值会决定内存分段是否被回收。-XX:G1MixedGCLiveThresholdPercent,默认为65%,意思是垃圾占内存分段比例要达到65%才会被回收。如果垃圾占比太低,意味着存活的对象占比高,在复制的时候会破费更多的工夫。
混合回收并不一定要进行8次。有一个阈值-XX:G1HeapWastePercent,默认值为10%,意思是容许整个堆内存中有10%的空间被节约,意味着如果发现能够回收的垃圾占堆内存的比例低于10%,则不再进行混合回收。因为GC会破费很多的工夫然而回收到的内存却很少。
g1 STAB避免漏标
能够简略了解为,当一个灰色对象勾销了对红色对象的援用,那么这个红色对象被变灰
这样做的毛病就是,这个红色对象有可能并没有彩色对象去援用它,然而它还是被变灰了,就会导致它和它的援用,原本应该被垃圾回收掉,然而此次GC存活了下来,就是所谓的浮动垃圾.其实这样是比拟能够忍耐的,只是让它多存活了一次GC而已,节约一点点空间,然而会比增量更新更省工夫.
SATB也是有副作用的。如果被批改援用的白对象就是要被收集的垃圾,这次的标记会让它躲过GC,这就是float garbage。因为SATB的做法精度比拟低,所以造成的float garbage也会比拟多。
https://www.jianshu.com/p/989...
https://www.jianshu.com/p/ac1...