cms参数:

UseConcMarkSweepGC:应用cms垃圾回收器CMSFullGCsBeforeCompaction:几次full gc整顿压缩一次 默认0UseCMSInitiatingOccupancyOnly:假如没有这个参数,只有第一次产生cms gc的时候会应用CMSInitiatingOccupancyFraction参数值 前面jvm会动静调整CMSInitiatingOccupancyFraction:指CMS在对内存占用率达到肯定的时候开始GC 默认92%CMSScavengeBeforeRemark:在CMS GC前启动一次ygc,目标在于缩小old gen对ygc gen的援用,升高remark时的开销(个别CMS的GC耗时 80%都在remark阶段)    CMSScheduleRemarkEdenSizeThreshold、CMSScheduleRemarkEdenPenetration,默认值别离是2M、50%。两个参数组合起来的意思是预清理后,eden空间应用超过2M时启动可中断的并发预清理,直到eden空间使用率达到50%时中断,进入从新标记阶段。

cms gc触发机会:
阈值查看机制:老年代的应用空间达到某个阈值,JVM的默认值是92%(jdk1.5之前是68%,jdk1.6之后是92%),或者能够通过CMSInitiatingOccupancyFraction和UseCMSInitiatingOccupancyOnly两个参数来设置;这个参数的设置须要看利用场景,设置得太小,会导致CMS频繁产生,设置得太大,会导致过多的并发模式失败。例如

动静查看机制:JVM会依据最近的回收历史,估算下一次老年代被耗尽的工夫,快到这个工夫的时候就启动一个并发周期。设置UseCMSInitiatingOccupancyOnly这个参数能够将这个个性敞开。

full gc触发的机会:

1:System.gc()。如果没有开启禁止调用system.gc() DisableExplicitGC;2:promotion failed:这种状况通常是对象要降职到老年代中时,发现老年代的内存不足了,所以要引发一次Full GC。对象的降职分为失常降职(活过15代)和提前降职(大对象、survival区装不下)。3:concurrent mode failure:在执行CMS GC的过程中同时有对象要放入老年代,而此时老年代空间有余造成的4:metaSpace空间不够5:jmap -dump:live触发

CMS进化为serial gc的状况:

 promotion failed 不会 导致fullGC中的CMS进化为serialGC concurrent mode failure会引起Full GC,这种状况下会应用Serial Old收集器,是单线程的,对GC的影响很大。

CMS GC 过程:CMS GC仅仅是堆old区进行回收。

1:初始标记 :在这个阶段,须要STW。这个过程从root set开始,只扫描到可能和root set间接关联的对象,并作标记。jdk1.8后这一步是并发的。这里的root set不蕴含年老代。2:并发标记 :这个阶段紧随初始标记阶段,在初始标记的根底上持续向下追溯标记。并发标记阶段,应用程序的线程和并发标记的线程并发执行,所以用户不会感触到进展。3:预清理阶段:这个阶段会解决在并发标记过程中eden区发生变化的援用(特指eden指向old gen的援用变动),此外还会解决dirty card中的援用。4:可中断预清理阶段:这个阶段次要解决from和to区域对象援用old gen的变动,同样也会持续解决dirty card的对象援用。触发的条件:Eden的占用量>CMSScheduleRemarkEdenSizeThreshold(默认为2M),中断的条件:Eden区占用量>CMSScheduleRemarkEdenPenetration(默认50%),或达到5秒钟。5:从新标记 :STW 扫一遍root set,root set蕴含年老代。CMS的remark须要从新扫描mod-union table里的dirty card外加整个根汇合,而此时整个young gen(不论对象死活)都会被当作根汇合的一部分,因此CMS remark有可能会十分慢。6:并发清理 :清理垃圾对象,这个阶段收集器线程和应用程序线程并发执行。7:并发重置 :这个阶段,重置CMS收集器的数据结构,期待下一次垃圾回收。

CMS的Precleaning(预清理)和AbortablePreclean(可中断的预清理)

预清理和可中断预清理这两个阶段并不是必须的,能够通过参数XX:-CMSPrecleaningEnabled敞开。

Free list space:cms gc回收会产生不间断的内存,用一个链表把他们连起来,当用户申请调配时,零碎从可利用空间表中删除一个结点调配之;当用户开释其所占内存时,零碎即回收并将它插入到可利用空间表中。

三色标记法:
彩色:从GCRoots开始,已扫描过它全副援用的对象,标记为彩色
灰色:扫描过对象自身,还没齐全扫描过它全副援用的对象,标记为灰色
红色:还没扫描过的对象,标记为红色

三色标记的漏标问题产生的起因:漏标会导致理当活着的对象被回收

有至多一个彩色对象在本人被标记之后指向了这个红色对象所有的灰色对象在本人援用扫描实现之前删除了对红色对象的援用

CMS的解决 INC barrier:

如果一个彩色对象增加了一个红色对象,就把这个彩色对象变灰。这样从新标记的时候就会持续扫描他。这个存有一项缺点:无奈发现 Concurrent Mark 期间堆外根集(寄存器、栈)的援用变动。为此在 concurrent mark 之后,须要一个 remark 阶段再 STW 扫一遍root set。