深入理解JAVA虚拟机读书笔记(5)

    上一节介绍的是垃圾回收算法,这一节介绍垃圾搜集器。何为垃圾收集器,其实就是讲之前的垃圾回收算法通过编程语言实现出来。

    在介绍下面的回收器之前,先来接收两个概念,并发、并行、吞吐量:

    并行:指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。

    并发:指用户线程与垃圾收集线程同时执行(但不一定是并行的,可能会交替执行),用户程序在继续运行,而垃圾收集程序运行于另一个CPU上。

    吞吐量:吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间),虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%

    下面根据上述的垃圾收集器来具体介绍与之对应的实现:

    1. 串行搜集器(一个GC单线程,且会暂停用户程序)

        实现:serial(用于新生代,采用复制算法)、serial old(用于年老代,采用标记/整理算法)。

        优点:Serial收集器对于桌面应用交互程序和运行在Client模式下的虚拟机来说是一个很好的选择。

        缺点:需要暂停用户线程,且停顿时间较长。

        

    2.  并行收集器(多个GC线程,且会暂停用户程序)

        实现:ParNew(用于新生代,采用复制算法)、Parallel Scavenge(用于新生代,采用复制算法,更关注吞吐量)、Parallel old(用于年老代,采用标记/整理算法)。

        优点:在中到大型的堆上,且系统处理器至少多于一个的情况。

        缺点:对于单个处理器来说,由于并行执行的开销(比如同步),ParNew的性能将会低于serial搜集器。不仅是单个处理器的时候,如果在容量较小的堆上,甚至在两个处理器的情况下,ParNew的性能都并非一定可以高过serial。

            

    3.并发收集器(一个或多个GC线程,在需要的阶段暂停用户程序,不需要的阶段和用户程序并发执行)

        实现:CMS收集器(用于年老代,采用标记/清除算法)。

        优点:真正意义上实现了应用程序与GC线程一起工作(一起是针对客户而言,而并不一定是真正的一起,有可能是快速交替)的搜集器。重视服务的响应速度,希望系统停顿时间最短,以给用户带来较好的体验

         CMS处理分为四个阶段:

                 1、初始标记:需要暂停应用程序,快速标记存活对象。

                 2、并发标记:恢复应用程序,并发跟踪GC Roots。

                 3、重新标记:需要暂停应用程序,重新标记跟踪遗漏的对象。

                 4、并发清除:恢复应用程序,并发清除未标记的垃圾对象。

          缺点:在并发阶段,它虽然不会导致用户线程停顿,但是会因为占用了一部分线程(或者说CPU资源)而导致应用程序变慢,总吞吐量会降低。其次,由于CMS并发清理阶段用户线程还在运行着,伴随程序运行自然就还会有新的垃圾不断产生,这一部分垃圾出现在标记过程之后,CMS无法在当次收集中处理掉它们,只好留待下一次GC时再清理掉。这一部分垃圾就称为“浮动垃圾”。最后一个缺点就是CMS使用的是标记清除法,会产生空间碎片,从而无法找到足够大的连续空间来分配当前对象,不得不提前触发一次Full GC。

            

     4.G1收集器(jdk1.7后出来,将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region(不需要连续)的集合。)

            

    上面介绍的6种垃圾搜集器都是针对不同内存区域设计的,我们需要给JVM的新生代和老年代选择相应的垃圾收集器,上面新生代垃圾搜集器有serial,ParNew和Parallel Scavenge三种,老年代垃圾搜集器有serial old,Parallel old和CMS三种。也就是说选择应该是3*3=9种,但是,事实上只有6种,因为有的垃圾搜集器由于具体实现方式等原因导致无法在一起工作。下图展示了可以组合工作的图。

                   

    六种组合是:serial-CMS、serial-serial old、ParNew-CMS、ParNew-Seria old、Parallel Scavenge-Serial Old、Parallel Scavege-Parallel old

    下面简单介绍下其中的几种组合

        1.serial-serial old:这个组合是最常见的,是client模式下默认的垃圾收集器组合,也可以使用参数-XX:+UseSerialGC强制开启。由于它实现相对简单,没有线程相关的额外开销(主要指线程切换与同步),因此非常适合运行于客户端PC的小型应用程序,或者桌面应用程序(比如swing编写的用户界面程序),以及我们平时的开发、调试、测试等。

        2.Parallel Scavenge-Parallel old:这个组合不常见,但是如果对吞吐量要求比较高或对停顿时间要求高的应用程序来说,是首选,这个组合是server模式下默认的组合,可以利用-XX:+UseParallelGC参数强制开启。

        3.ParNew-CMS(serial old):这个组合在平常开发中不常见,但是在对相应时间要求较高的应用程序来说,是首选,这个组合使用-XX:+UseConcMarkSweepGC开启。这个组合在新生代使用并行,因此新生代GC速度非常快,老年代使用并发,因此老年代停顿时间较短,适用于一些需要长期运行且对相应时间有一定要求的后台程序,最典型的的就是WEB应用程序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值