JVM垃圾收集器

2019-07-24  本文已影响0人  代代代个码

— —最近又刷了一遍JVM的重点章节,想着记录点东西,摘自《深入理解Java虚拟机》.

1. Serial收集器(新生代)
* 单线程:使用一个CPU或一条收集线程完成垃圾收集,且期间必须暂停其他所有的工作线程(stop the world).
* 新生代采用复制算法,暂停所有用户线程;
* 适用于Client模式下运行的虚拟机.或者单个CPU环境下,不涉及线程交互所带来的额外开销.
2. ParNew收集器(新生代)
* 多线程:可以理解为Serial的多线程版本,运行机制基本一致.默认开启的线程数与CPU核数一致.
* 新生代采用复制算法,暂停所有用户线程;
* 单核环境中没有Serial收集器性能好;甚至双核的配置下,由于涉及线程交互的开销,ParNew的性能也很难超越Sarial.
* 很多运行在server模式下的虚拟机中首选的收集器,原因如下:
    1)目前除了Serial收集器之外只有ParNew可以与CMS收集器配合工作.
    2)服务器的配置越来越高,CPU数量不断增大
3. Parallel Scavenge(新生代)
* 多线程,采用复制算法,应用于新生代.
* 不需要暂停用户线程.
* 关注点与其他收集器不同:
    PS关注系统的吞吐量(Throughput, 指cpu用于运行用户代码的时间与cpu总共耗时的比值);
    其他收集器则关注与GC时用户线程的停顿时间。
    停顿时间越短就越适合与用户进行交互的程序,吞吐量高则适用于后台计算任务.
* 参数调控:
    1)-XX:MaxGCPauseMillis 控制最大的垃圾收集停顿时间
        此参数的值并不是越小越好,因为停顿时间简短是通过牺牲吞吐量和新生代空间来换取;
        新生代缩小,垃圾收集频率增大,吞吐量下降
    2)-XX:GCTimeRatio 直接设置吞吐量大小
        设置为(0, 100)的整数,代表垃圾收集时间占用总时间的比率.
    3) -XX:UseAdaptiveSizePolicy 开关参数.
        该参数打开后,虚拟机会监控系统运行的性能信息,动态调整一些参数以获取最适合的停顿时间或最大吞吐量.
        称为GC自适应的调节策略(GC Ergonomic).
4. Serial Old(老年代)
* 单线程,是Serial收集器的老年代版本.
* 老年代采用标记-整理算法,暂停所有用户线程.
* 主要用于Client模式的虚拟机.
* 在Server模式下,有两个用途:
    1)作为CMS收集器的备选方案,在并发收集发生Concurrent Mode Failure时使用;
    2)与新生代的Parallel Scavenge收集器配合使用(JDK 1.5之前)
5. Parallel Old(老年代)
* 多线程,是Parallel Scavenge的老年代版本.
* 老年代采用标记-整理算法,不需要暂停用户线程(JDK 1.6之后引入)
* Parallel Scevenge得以摆脱和Serial Old配合使用的尴尬局面,和Parallel Old配合真正实现高吞吐量.
6. CMS收集器(Concurrent Mark Sweep)
* 多线程,致力于获取最短停顿时间,重视提高服务器的响应速度.
* 采用标记-清除算法,分为四个步骤:
    1)初始标记(CMS initial mark)
        仅仅标记一下GCRoots能直接关联到的对象,速度很快.
    2) 并发标记(CMS concurrent mark)
        进行GCRoots Tracing.此阶段和用户程序并发进行.
    3) 重新标记(CMS remark)
        修正并发标记期间因用户程序继续运作导致标记产生变动的那部分对象的标记记录.
        时间会比初始标记长一点,但远比并发标记的时间短.
    4)并发清除(CMS concurrent sweep)
    其中,初始标记和重新标记需要stop the world.
* CMS收集器具有并发收集、低停顿的优点.也称为并发低停顿收集器(Concurrent Low Pause Collector).
* CMS具有如下3个明显的缺点:
    1)对CPU极其敏感.
        CMS默认启动的回收线程是(CPU数量 + 3)/ 4,即CPU数量在4以上时,回收线程占据不少于25%的CPU资源;
        但是CPU数量不足4时,回收线程要占据一半的CPU资源.
    2)无法处理浮动垃圾(Floating Garbage).
        并发清理阶段,用户程序新产生的垃圾无法在本次GC中被清除,这部分垃圾称为浮动垃圾.所以CMS收集器需要
        预留一部分空间用于并发收集时用户程序的运作.JDK 1.6中,CMS收集器启动的阈值默认为92%.若CMS运行期间,
        无法满足用户程序所需要的内存空间,就会出现Cocurrent Mode Failure.此时,JVM将启动备用方案:临时
        启用Serial Old收集器来重新进行老年代的垃圾回收.
    3)容易产生内存碎片.
        由于CMS采用标记-清除算法,会产生大量内存碎片,导致老年代还有很多空闲内存,但是无法提供连续内存空间来存放大对象.
        这种情况会提前触发一次FullGC.
        为解决这个问题,CMS收集器提供两个参数:
        -XX:+UseCMSCompactAtFullCollection开关参数.指定FullGC时开启内存碎片整理的过程,该过程无法与用户程序并发进行.
        -XX:CMSFullGCsBeforeCompaction.该参数指定进行多少次非压缩的FullGC后,进行一次带压缩的FullGC(默认是0,即每次都带压缩)
7. G1(Garbage-First)
* 面向服务端
* G1是目前主流趋势,打算抽时间重点整理。。。
上一篇下一篇

猜你喜欢

热点阅读