5.2垃圾收集器SerialParallelParNewCMS详解

? 如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现 。虽然对各个收集器进行比较,但并非为了挑选出一个最好的收集器 。因为直到现在为止没有出现一个最用的的垃圾收集器,更加没有万能的垃圾收集器,能做的就是根据具体应用场景选择适合自己的垃圾收集器 。试想一下:如果有一任何场景下都适用的完美收集器存在,那么Java虚拟机就不会实现那么多不同的垃圾收集器了 。
? 上图虚线上方是年轻代垃圾收集器,下方是老年代垃圾收集器,同一个颜色表示使用时是成对出现的 。
1.1收集器(-XX:+ -XX:+) [?s?ri?l]
? (串行)收集器是最基本、历史最悠久的垃圾收集器了 。看名字就知道这个收集器是一个单线程收集器了 。它的 “单线程” 的意义不仅仅意味着它只会使用一条垃圾收集线程去完成垃圾收集工作,更重要的是它在进行垃圾收集工作的时候必须暂停其他所有的工作线程( “Stop The World” ),直到它收集结束 。
新生代采用复制算法,老年代采用标记-整理算法 。
【5.2垃圾收集器SerialParallelParNewCMS详解】? 虚拟机的设计者们当然知道Stop The World带来的不良用户体验,所以在后续的垃圾收集器设计中停顿时间在不断缩短(仍然还有停顿,寻找最优秀的垃圾收集器的过程仍然在继续) 。
? 但是收集器有没有优于其他垃圾收集器的地方呢?当然有,它简单而高效(与其他收集器的单线程相比) 。收集器由于没有线程交互的开销,自然可以获得很高的单线程收集效率 。
重点: Old收集器是收集器的老年代版本,它同样是一个单线程收集器 。它主要有两大用途:一种用途是在JDK1.5以及以前的版本中与 收集器搭配使用,另一种用途是作为CMS收集器的后备方案 。
1.2收集器(-XX:+(年轻代),-XX:+(老年代)) [?p?r?lel]
? 收集器其实就是收集器的多线程版本,除了使用多线程进行垃圾收集外,其余行为(控制参数、收集算法、回收策略等等)和收集器类似 。默认的收集线程数跟cpu核数相同,当然也可以用参数(-XX:)指定收集线程数,但是一般不推荐修改 。
?收集器关注点是吞吐量(高效率的利用CPU) 。CMS等垃圾收集器的关注点更多的是用户线程的停顿时间(提高用户体验) 。所谓吞吐量就是CPU中用于运行用户代码的时间与CPU总消耗时间的比值 。收集器提供了很多参数供用户找到最合适的停顿时间或最大吞吐量,如果对于收集器运作不太了解的话,可以选择把内存管理优化交给虚拟机去完成也是一个不错的选择 。
新生代采用复制算法,老年代采用标记-整理算法 。
重点: Old收集器是 收集器的老年代版本 。使用多线程和“标记-整理”算法 。在注重吞吐量以及CPU资源的场合,都可以优先考虑收集器和 Old收集器(JDK8默认的新生代和老年代收集器) 。
1.3 收集器(-XX:+)
收集器其实跟收集器很类似,区别主要在于它可以和CMS收集器配合使用 。
新生代采用复制算法,老年代采用标记-整理算法 。
它是许多运行在模式下的虚拟机的首要选择,除了收集器外,只有它能与CMS收集器配合工作 。
1.4 CMS收集器(****-XX:+(old))
CMS( Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器 。它非常符合在注重用户体验的应用上使用,它是虚拟机第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程(基本上)同时工作 。
从名字中的Mark Sweep这两个词可以看出,CMS收集器是一种 “标记-清除”算法实现的,它的运作过程相比于前面几种垃圾收集器来说更加复杂一些 。整个过程分为四个步骤: