垃圾回收器
所有连线的都可以进行组合使用
常用的组合为:1.ParNew-CMS 2.Serial-SerialOld 3.ParallelScavenge-ParallelOld
现在没有任何特殊配置jvm默认的就是3
Serial 年轻代 串行回收
单线程对垃圾进行回收,当进行垃圾回收的时候其他所有工作线程都要停止等待,这个等待叫做STW(stop the word)也叫停顿时间,单CPU效率最高。(需要找一个安全点进行STW,safe point)虚拟机是Client模式的默认垃圾回收器。以前内存比较小的时候很适合,现在极少使用。
SerialOld 老年代 串行回收
和Serial年轻代一样
ParallelScavenge 年轻代 并行回收
当进行垃圾回收的时候是由多线程并行处理垃圾,不是单线程,也是会存在STW
ParallelOld 老年代 并行回收
和ParallelScavenge 相同,为在老年代。
ParNew 年轻代 配合CMS的并行回收
是和ParallelScavenge 一样的,主要就是为了配合CMS使用,只是比ParallelScavenge多了些增强,做了哪些增强呢?例如:在CMS某些阶段的时候ParNew也会运行
CMS 老年代 并发回收
CMS为1.4之后引用,开启了并发回收,CMS本身存在比较多的问题,因此目前应该没有任何一个jdk版本默认是CMS。
什么是并发呢?当进行垃圾回收的时候工作线程是不需要停止的,可以接着运行。
无法忍受STW才产生了CMS的并发回收,小内存的情况下清理起来很快,内存特别大的时候清理时间就很长
老年代分配不下了就触发了CMS
CMS的四个阶段
1.初始标记:直接找到根对象进行标记(STW不长)
//预标记阶段
2.并发标记:并发标记耗时较长和工作线程一块进行
3.重新标记:多数垃圾在并发标记中标记完了,在并发标记中产生的新垃圾要再标记一下(STW不长)
4.并发清理:和工作线程一块,这时候也会产生新的垃圾,这些垃圾称为浮动垃圾(等着下次CMS进行清理)
//整理阶段
CMS的问题
1.MemoryFragmentation:内存碎片化
内存特别大的时候,老年代产生很多碎片的时候,年轻代过来找不到空间了,年轻代的对象不能向老年代增加了,CMS就会把SerialOld用单线程进行标记压缩
2.FloatingGarbage:浮动垃圾
并发清理之后会产生浮动垃圾,此时老年代满了就会是用SerialOld就会有很长的STW
解决方案:1.降低触发CMS的阈值 2.保持老年代有足够的空间
ps:java -XX:CMSInitiatingOccupancyFraction 68%
可以通过调整这个百分比值进行调整产生FGC的触发条件,让它有足够的空间产生浮动垃圾不让它直接就满了,使得CMS使用SerialOld进行FGC