JVM之垃圾收集算法及垃圾收集器详解

JVM之垃圾收集算法及垃圾收集器详解

一、垃圾回收算法

  • 标记清除算法
  • 复制算法
  • 标记压缩算法(Mark-Compact)
  • 分代算法

1.1 标记清除算法

标记清除算法将垃圾回收分为两个阶段:标记阶段清除阶段
标记阶段:首先经过根节点,标记全部从根节点开始的可达对象。未被标记的对象就是未被引用的垃圾对象。
清除阶段:清除全部未被标记的对象。
标记清除算法可能产生的最大问题是空间碎片
注意:标记清除算法先经过根节点标记全部可达对象,而后清除全部不可达对象,完成垃圾回收。算法

1.2 复制算法

eden ===> from to,就是使用的复制算法
优势:不会产生碎片
缺点:浪费空间多线程

1.3 标记压缩算法

标记压缩算法是一种老年代的回收算法。并发

1.4 分代收集算法

新生代能够用复制算法。
老年代可使用标记-清除算法标记-整理算法jvm

二、垃圾收集器

  • 串行收集器
  • 并行收集器
  • CMS
  • G1

2.1 串行回收器

串行回收器是指使用单线程进行垃圾回收的回收器。性能

2.1.1 新生代串行回收器

串行回收器主要有两个特色:线程

  • 它仅仅使用单线程进行垃圾回收
  • 它是独占式的垃圾回收

在串行收集器进行垃圾回收时,Java应用程序中的线程都须要暂停,等待垃圾回收的完成。这种现象称之为Stop-The-World。在实时性要求较高的应用场景中,这种现象每每是不能被接受的。code

新生代串行处理器使用复制算法对象

使用-XX:+UseSerialGC参数能够指定使用新生代串行收集器和老年代串行收集器。内存

2.1.2 老年代串行回收器

老年代串行收集器使用的是标记压缩算法。和新生代串行收集器同样,它也是一个串行的、独占式的垃圾回收器。工作流

若是要启动老年代串行回收器,能够尝试使用如下参数:

  • -XX:+UseSerialGC:新生代、老年代都使用串行回收器
  • -XX:+UseParNewGC:新生代使用ParNew回收器,老年代使用串行收集器
  • -XX:+UseParallelGC:新生代使用ParallelGC回收器,老年代使用串行收集器

2.2 并行收集器

它只是在串行回收器上作了改进,使用多个线程同时进行垃圾回收。

2.2.1 新生代ParNew回收器

它是独占式的。
在并发能力比较强的CPU上,它产生的停顿时间要短于串行回收器,而在单CPU或者并发能力较弱的系统中,并行回收器的效果不会比串行回收器好,因为多线程的压力,它的实际表现极可能比串并回收器差。

启动新生代ParNew回收器:

  • -XX:+UseParNewGC:新生代使用ParNew回收器,老年代使用串行回收器。
  • -XX:+UseConcMarkSweepGC:新生代使用ParNew回收器,老年代使用CMS。

ParNew回收器的线程数量能够经过-XX:ParallelGCThreads参数指定。

2.2.2 新生代ParallelGC回收器

新生代ParallelGC回收器关注系统吞吐量,使用复制算法

启动新生代ParallelGC回收器:

  • -XX:+UseParallelGC:新生代使用ParallelGC回收器,老年代使用串行回收器。
  • -XX:+UseParallelOldGC:新生代使用ParallelGC回收器,老年代使用ParallelOldGC。

ParallelGC回收器提供了两个重要的参数用于控制系统的吞吐量:

  • -XX:MaxGCPauseMillis:设置最大垃圾收集停顿时间
  • -XX:GCTimeRatio:设置吞吐量大小

这是它与ParNew回收器的一个不一样之处,另一个不一样之处是它还支持一种自适应的GC调整策略。使用-XX:+UseAdaptiveSizePolicy能够打开自适应GC策略。

2.2.3 老年代ParallelOldGC回收器

老年代ParallelOldGC回收器也是一种多线程并行的收集器。它也是一种关注吞吐量的收集器。它使用标记压缩算法,它在JDK1.6中才可使用。

使用-XX:+UseParallelOldGC能够在新生代使用ParallelGC回收器,老年代使用ParallelOldGC回收器。参数-XX:ParallelGCThreads也能够用于设置垃圾回收时的线程数量。

2.3 CMS收集器

它是非独占的。

ParallelGCParallelOldGC不一样,CMS回收器主要关注于系统停顿时间。CMS是Concurrent Mark Sweep的缩写,意为并发标记清除,从名称上就能够得知,它使用的是标记清除算法,同时它又是一个使用多线程并行回收的垃圾回收器。

2.3.1 CMS主要的设置参数
  • -XX:-CMSPrecleaningEnabled
    关闭预清理
  • -XX:+UseConcMarkSweepGC
    启动CMS回收器的参数。CMS是多线程回收器,设置合理的工做线程数量也对系统性能有重要的影响。(同时也表示新生代使用ParNewGC
  • -XX:CMSInitiatingOccupancyFraction
    指定当老年代空间使用率达到多少时,进行一次CMS垃圾回收。
  • -XX:+UseCMSCompactAtFullCollection
    这个开关可使CMS在垃圾收集完成后,进行一次内存碎片整理,内存碎片的整理不是并发并行的。
  • -XX:CMSFullGCsBeforeCompaction
    能够用于设定进行多少次CMS回收后,进行一次内存压缩。

注意:
并发是指收集器和应用线程交替执行。
并行是指应用程序中止,同时由多个线程一块儿执行GC。
所以并行回收器不是并发的,由于并行回收器执行时,应用程序彻底挂起,不存在交替执行的步骤。CMS回收器是一个关注停顿的垃圾收集器。同时CMS回收器在部分工做流程中,能够与用户程序同时运行,从而下降应用程序的停顿时间。

2.3.2 有关Class的回收

在使用CMS回收器时,若是须要回收Perm区,那么默认状况下,仍是须要触发一次Full GC的。若是但愿使用CMS回收Perm区,则必需要打开-XX:+CMSClassUnloadingEnabled开关,若是条件容许,那么系统会使用CMS的机制回收Perm区Class数据。

2.4 G1回收器

G1回收器是在JDK1.7中正式使用的全新垃圾回收器,从长期目标来看,它是为了取代CMS回收器。

从分代上看,G1依然属于分代垃圾回收器,它会区分年轻代老年代,依然有eden区和survivor区,但从堆的结构上看,它并不要求整个eden区,年轻代或者老年代都连续。它使用了分区算法

做为CMS的长期替代方案,G1同时使用了全新的分区算法,其特色以下:

  • 并行性:G1在回收期间,能够由多个GC线程同时工做,有效利用多核计算能力。
  • 并发性:G1拥有与应用程序交替执行的能力,部分工做能够和应用程序同时执行,所以通常来讲,不会在整个回收期间彻底阻塞应用程序。
  • 分代GC:G1依然是一个分代收集器,可是和以前回收器不一样,它同时兼顾年轻代和老年代。
  • 空间整理:G1在回收过程当中,会进行适当的对象移动,不像CMS,只是简单地标记清理对象,在若干次GC后,CMS必须进行一次碎片整理。而G1不一样,它每次回收都会有效地复制对象,减小空间碎片。
  • 可预见性:因为分区的缘由,G1能够只选取部分区域进行内存回收,这样缩小了回收的范围,所以对于全局停顿也能获得较好的控制。
2.4.1 G1的内存划分和主要收集过程

G1的手机过程可能有4个阶段:

  • 新生代GC
  • 并发标记周期
  • 混合收集
  • 若是须要,可能会进行Full GC
相关文章
相关标签/搜索