垃圾回收器

收集算法是内存回收的方法论,垃圾收集器就是内存回收的具体实现。收集器主要分三类:串行收集器、并行收集器以及并发收集器。java

1、基础概念

一、并发和并行算法

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

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

二、新生代 GC 和老年代GC性能

    a:新生代GC(Minor GC):指发生在新生代的垃圾收集动做,由于Java对象大多都具有朝生夕灭的特性,因此Minor GC很是频繁,通常回收速度也比较快。网站

    b:老年代GC(Major GC / Full GC):指发生在老年代的GC,出现了Major GC,常常会伴随至少一次的Minor GC(但非绝对的)。Major GC的速度通常会比Minor GC慢10倍以上。spa

三、吞吐量线程

        吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即吞吐量 = 运行用户代码时间 /(运行用户代码时间 + 垃圾收集时间)对象

 虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。blog

 

二垃圾收集器

一、Serial收集器

       串行收集器是最古老,最稳定以及效率高的收集器,可能会产生较长的停顿,只使用一个线程去回收。

新生代、老年代使用串行回收;新生代复制算法、老年代标记-压缩;垃圾收集的过程当中会Stop The World(服务暂停)

参数控制:-XX:+UseSerialGC 串行收集器

二、ParNew收集器

ParNew收集器其实就是Serial收集器的多线程版本。新生代并行,老年代串行;新生代复制算法、老年代标记-压缩

参数控制:-XX:+UseParNewGC ParNew收集器

              -XX:ParallelGCThreads 限制线程数量

Serial收集器 VS ParNew收集器

       ParNew收集器在单CPU的环境中绝对不会有比Serial收集器更好的效果,甚至因为存在线程交互的开销,该收集器在经过超线程技术实现的两个CPU的环境中都不能百分之百地保证能够超越Serial收集器。

然而,随着可使用的CPU的数量的增长,它对于GC时系统资源的有效利用仍是颇有好处的。

三、Parallel Scavenge收集器

       是一个新生代收集器,他也是使用复制算法的收集器,又是并行的多线程收集器。Parallel收集器更关注系统的吞吐量

也能够经过参数控制GC的时间不大于多少毫秒或者比例;新生代复制算法、老年代标记-压缩

参数控制:-XX:+UseParallelGC 使用Parallel收集器+ 老年代串行

Parallel Scavenge收集器 VS CMS等收集器

      CMS等收集器的关注点是尽量地缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量(Throughput)

因为与吞吐量关系密切,Parallel Scavenge收集器也常常称为“吞吐量优先”收集器。

Parallel Scavenge收集器 VS ParNew收集器

        Parallel Scavenge收集器与ParNew收集器的一个重要区别是它具备自适应调节策略。

GC自适应的调节策略

         Parallel Scavenge收集器有一个参数-XX:+UseAdaptiveSizePolicy。当这个参数打开以后,就不须要手工指定新生代的大小。

Eden与Survivor区的比例、晋升老年代对象年龄等细节参数了,虚拟机会根据当前系统的运行状况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量,这种调节方式称为GC自适应的调

节策略(GC Ergonomics)。

四、Serial Old收集器

     它是Serial收集器的老年代版,它一样是一个单线程收集器,使用“标记--整理”算法。

五、Parallel Old 收集器

     是Parallel Scavenge收集器的老年代版,使用多线程与“标记--整理”算法。

六、CMS收集器

        是一种以获取最短回收停顿时间为目标的收集器。目前很大一部分的java应用集中在互联网站或者B/S系统的服务端上,这类应用尤为重视服务的响应速度,但愿系统停顿时间最短,以给用户带来较好的体验。

CMS收集器就很是符合这类应用的需求。

CMS收集器是基于“标记--清除”算法实现的, 他的运做过程相对于前几种收集器来讲更复杂一些,整个过程分为4个步骤:

      a、初始标记(CMS inital mark):须要“stop the world”,但只标记一下GC Roots能直接关联的对象,速度很快。

      b、并发标记(CMS concurrent mark):是GC Roots Tracing的过程,花费时间长

      c、从新标记(CMS remark):是为了修正并发标记期间因用户程序继续运行而致使标记产生变更的那一部分对象的标记记录,这个阶段时间通常会比初始标记阶段稍长一些,但远比并发标记的时间短。

      d、并发清除(CMS concurrent sweep):是并发清除无用对象。

 因为整个过程当中耗时最长的并发标记和并发清除过程收集器线程均可以与用户线程一块儿工做,因此,从整体上来讲,CMS收集器的内存回收过程是与用户线程一块儿并发执行的。

优势

       CMS是一款优秀的收集器,它的主要优势在名字上已经体现出来了:并发收集、低停顿

缺点

     (1)CMS收集器对CPU资源很是敏感

        在并发阶段,它虽然不会致使用户线程停顿,可是会由于占用了一部分线程(或者说CPU资源)而致使应用程序变慢,总吞吐量会下降。

     (2)CMS收集器没法处理浮动垃圾

     因为CMS并发清理阶段用户线程还在运行着,伴随程序运行天然就还会有新的垃圾不断产生,这一部分垃圾出如今标记过程以后,CMS没法在当次收集中处理掉它们,只好留待下一次GC时再清理掉。这一部分垃

圾就称为“浮动垃圾”。

     (3)CMS收集器会产生大量空间碎片

     CMS是一款基于“标记—清除”算法实现的收集器,这意味着收集结束时会有大量空间碎片产生。

空间碎片过多时,将会给大对象分配带来很大麻烦,每每会出现老年代还有很大空间剩余,可是没法找到足够大的连续空间来分配当前对象,不得不提早触发一次Full GC。

七、G1收集器

G1(Garbage-First)是一款面向服务端应用的垃圾收集器。

与CMS收集器相比有如下优势

(1)没有大量空间碎片

   与CMS的“标记—清理”算法不一样,G1从总体来看是基于“标记—整理”算法实现的收集器,从局部(两个Region之间)上来看是基于“复制”算法实现的。

(2)可预测的停顿

   这是G1相对于CMS的另外一大优点,下降停顿时间是G1和CMS共同的关注点,但G1除了追求低停顿外,还能创建可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片断内,消耗在垃圾收集上的

时间不得超过N毫秒。

G1收集器执行过程

a、初始标记(Initial Marking)

初始标记阶段仅仅只是标记一下GC Roots能直接关联到的对象,而且修改TAMS的值,让下一阶段用户程序并发运行时,能在正确可用的Region中建立新对象,这阶段须要停顿线程,但耗时很短。

b、并发标记(Concurrent Marking)

并发标记阶段是从GC Root开始对堆中对象进行可达性分析,找出存活的对象,这阶段耗时较长,但可与用户程序并发执行。

c、最终标记(Final Marking)

最终标记阶段是为了修正在并发标记期间因用户程序继续运做而致使标记产生变更的那一部分标记记录,虚拟机将这段时间对象变化记录在线程Remembered Set Logs里面,最终标记阶段须要把Remembered Set

Logs的数据合并到Remembered Set中,这阶段须要停顿线程,可是可并行执行。

d、筛选回收(Live Data Counting and Evacuation)

筛选回收阶段首先对各个Region的回收价值和成本进行排序,根据用户所指望的GC停顿时间来制定回收计划,这个阶段其实也能够作到与用户程序一块儿并发执行,可是由于只回收一部分Region,时间是用户可控制

的,并且停顿用户线程将大幅提升收集效率。

 

3、经常使用的收集器组合

虽然咱们是在对各个收集器进行比较,但并不是为了挑选出一个最好的收集器。由于直到如今为止尚未最好的收集器出现,更加没有万能的收集器,因此咱们选择的只是对具体应用最合适的收集器。

经常使用的收集器组合 

  新生代GC策略 年老代GC策略 说明
组合1 Serial Serial Old
Serial和Serial Old都是单线程进行GC,特色就是GC时暂停全部应用线程。
组合2 Serial CMS+Serial Old CMS(Concurrent Mark Sweep)是并发GC,实现GC线程和应用线程并发工做,不须要暂停全部应用线程。另外,当CMS进行GC失败时,会自动使用Serial Old策略进行GC。
组合3
ParNew
CMS
使用-XX:+UseParNewGC选项来开启。ParNew是Serial的并行版本,能够指定GC线程数,默认GC线程数为CPU的数量。可使用-XX:ParallelGCThreads选项指定GC的线程数。
若是指定了选项-XX:+UseConcMarkSweepGC选项,则新生代默认使用ParNew GC策略。
组合4
ParNew
Serial Old 使用-XX:+UseParNewGC选项来开启。新生代使用ParNew GC策略,年老代默认使用Serial Old GC策略。
组合5
Parallel Scavenge
Serial Old
Parallel Scavenge策略主要是关注一个可控的吞吐量:应用程序运行时间 / (应用程序运行时间 + GC时间),可见这会使得CPU的利用率尽量的高,适用于后台持久运行的应用程序,而不适用于交互较多的应用程序。
组合6
Parallel Scavenge
Parallel Old
Parallel Old是Serial Old的并行版本

 

组合7
G1GC
G1GC
-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC        #开启
-XX:MaxGCPauseMillis =50                  #暂停时间目标
-XX:GCPauseIntervalMillis =200          #暂停间隔目标
-XX:+G1YoungGenSize=512m            #年轻代大小
-XX:SurvivorRatio=6                            #幸存区比例

图形展现

图中展现了7种做用于不一样分代的收集器,若是两个收集器之间存在连线,就说明它们能够搭配使用。虚拟机所处的区域,则表示它是属于新生代收集器仍是老年代收集器。

相关文章
相关标签/搜索