JVM学习04——垃圾收集器

  如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。这里讨论的收集器基于JDK 1.7Update 14之后的HotSpot虚拟机。

这里写图片描述

如图展示了7种作用于不同分代的收集器,如果两个收集器之间存在连线,就说明他们可搭配使用。

1.Serial收集器
  Serial收集器是一个单线程的新生代垃圾收集器,使用复制收集算法。它的“单线程”是指,它在进行垃圾收集时必须停止其他所有的工作线程。优点:在单线程环境中,Serial收集器没有与其他线程交互的开销,专注垃圾收集,更加简单高效。
2.ParNew收集器
  ParNew收集器实际为Serial收集器的多线程版本,收集新生代垃圾使用复制算法。行为与Serial收集器基本一样。可以使用 -XX:ParallelGCThreads参数来限制垃圾收集的线程数。

3.Parallel Scavenge收集器
  Parallel Scavenge收集器是一个新生代收集器,使用复制算法,而且是并行的多线程收集器。 parallel Scavenge收集器的特点是它的关注点与其他收集器不同,CMS等收集器的关注点是尽可能地缩短垃圾收集时用户线程的停顿时间,而parallel Scavenge收集器的目标则是达到一个可控制的吞吐量。吞吐量= 程序运行时间/(程序运行时间 + 垃圾收集时间),虚拟机总共运行了100分钟。其中垃圾收集花掉1分钟,那吞吐量就是99%。

4.Serial Old收集器

   Serial Old是Serial收集器的老年代版本,它同样使用一个单线程执行收集,使用“标记-整理”算法。主要使用在Client模式下的虚拟机。
5.Parallel Old收集器

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

6.CMS(Concurrent Mark Sweep)收集器
  CMS收集器是一种以获取最短回收停顿时间为目标的收集器,基于“标记-清除”算法实现。收集过程分4个步骤:

  • 初始标记(CMS initail mark)
  • 并发标记(CMS concurrent mark)
  • 重新标记(CMS remark)
  • 并发清除(CMS concurrent sweep)
      其中初始标记重新标记这两个步骤任然需要停顿其他用户线程。初始标记仅仅只是标记出GC ROOTS能直接关联到的对象,速度很快,并发标记阶段是进行GC ROOTS 根搜索算法阶段,会判定对象是否存活。而重新标记阶段则是为了修正并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间会被初始标记阶段稍长,但比并发标记阶段要短。

      CMS是一款优秀的收集器。主要优点是:并发收集,低停顿。但是它有以下三个明显缺点:

    1. CMS收集器对CPU资源非常敏感。在并发阶段,虽然不会导致用户线程停顿,但是会占用CPU资源而导致引用程序变慢,总吞吐量下降。CMS默认启动的回收线程数是:(CPU数量+3) / 4。
    2. 无法处理浮动垃圾,并且可能产生Concurrent Mode Failure从而导致另一次Full GC。
      并发清除时,用户线程是可以同时运行的,此时用户线程会产生新的垃圾,这部分垃圾在标记过程之后产生,本次GC已经不能进行标记后清除,只能留到下次GC时处理,被称为浮动垃圾
      由于CMS的收集线程执行时,用户线程也是会同时执行的,导致CMS收集器无法像其它老年代收集器那样在老年代内存几乎耗尽时再进行GC,必须为用户线程预留部分内存(低版本JDK默认值为68%,JDK6及以上版本默认值为92%将),如果预留内存无法满足用户线程的执行,将会出现Concurrent Mode Failure,此时虚拟机将会启动备用方案,调用Serial Old收集器执行一次Full GC,这将导致较长的收集停顿
      -XX:CMSInitiatingOccupancyFraction 设置GC触发的百分比,太高会导致过多的Concurrent Mode Failure,太低则影响性能,仅对CMS收集器生效。
    3. CMS是基于“标记-清除”算法实现的收集器,使用“标记-清除”算法收集后,会产生大量碎片。空间碎片太多时,将会给对象分配带来很多麻烦,比如说大对象,内存空间找不到连续的空间来分配不得不提前触发一次Full GC。为了解决这个问题,CMS收集器提供了一个-XX:UseCMSCompactAtFullCollection开关参数,用于在Full GC之后增加一个碎片整理过程,还可通过-XX:CMSFullGCBeforeCompaction参数设置执行多少次不压缩的Full GC之后,跟着来一次碎片整理过程。

7.G1(Garbage-First)收集器

   G1(Garbage First)收集器是JDK1.7提供的一个新收集器,G1收集器基于“标记-整理”算法实现,也就是说不会产生内存碎片。还有一个特点之前的收集器进行收集的范围都是整个新生代或老年代,而G1将整个Java堆(包括新生代,老年代)。

部分垃圾收集器参数
-XX:+UseSerialGC 使用Serial+Serial Old的收集器组合

-XX:+UseParNewGC 使用ParNew+Serial Old的收集器组合

-XX:+UseConcMarkSweepGC 使用ParNew+CMS/Serial Old(Serial Old为备用)的收集器组合

-XX:+UseParallelGC 使用Parallel Scavenge+Serial Old的收集器组合

-XX:+UseParallelOldGC 使用Parallel Scavenge+Parallel Old的收集器组合

-XX:+UseG1GC 使用用G1收集器进行内存回收

这里写图片描述

注:
1.本文为《深入理解Java虚拟机—JVM高级特性及最佳实践》阅读笔记。
2.本文许多文字内容来源于
http://blog.csdn.net/java2000_wl/article/details/8030172

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值