所有分类
  • 所有分类
  • 未分类

JVM–垃圾回收器的详解/对比

简介

本文介绍Java的垃圾回收器,包括:JDK默认的垃圾回收器、CMS与G1的区别、年轻代回收器、老年代回收器。

JDK默认的垃圾回收器

查看默认的垃圾回收器的方法

命令

java -XX:+PrintCommandLineFlags -version

结果:

我是JDK8,可看到:默认的垃圾回收器是并行垃圾回收器(UseParallelGC),此垃圾回收器的特点是:

  1. 并行执行,可发挥多核的优势,尽可能减少垃圾收集占用的时间,提高吞吐量。
  2. 垃圾回收时应用程序会停止,可调整 JVM 参数来平衡吞吐量和暂停时间。
  3. 年轻代垃圾回收器:Parallel Scavenge,使用复制算法进行垃圾回收。老年代垃圾回收器:Parallel Old,使用标记-整理算法进行垃圾回收。
  4. 并行垃圾回收期间,若用户线程继续分配大量对象并释放,可能会产生新的内存碎片。这可能会影响到后续的对象分配效率。为缓解这个问题,可使用其他垃圾回收器,如 G1(Garbage-First)垃圾回收器,它使用了更先进的算法来处理内存碎片问题。

JDK版本的默认垃圾回收器

版本年轻代老年代备注
JDK6PSScavenge(Parallel Scavenge)PSMarkSweep (Parallel Scavenge)简称:PSPS
JDK7PSScavenge(Parallel Scavenge)PSParallelCompact(Parallel Old)简称:PSPO
JDK8PSScavenge(Parallel Scavenge)PSParallelCompact(Parallel Old)简称:PSPO
JDK11G1G1

年轻代回收器

Parallel Scavenge与Parnew的区别

Parallel Scavenge(并行回收)与Parnew(并行回收)

区别一:搭配的老年代收集器

Parallel Scavenge:搭配的老年代垃圾收集器是Parallel Old,不能搭配CMS。

ParNew:可以搭配老年代垃圾收集器CMS。

区别二:参数

Parallel Scavenge收集器提供了两个参数用于精确控制吞吐量:-XX:MaxGCPauseMillis(最大垃圾收集停顿时间)和-XX:GCTimeRatio(设置吞吐量大小)。另外也要注意-XX:+UseAdaptiveSizePolicy参数。

-XX:MaxGCPauseMillis

设置最大GC暂停时间的目标(以毫秒为单位)。这是一个软目标,并且JVM将尽最大的努力来实现它。默认情况下,没有最大暂停时间值。
示例显示如何将最大目标暂停时间设置为500ms:-XX:MaxGCPauseMillis = 500

当然你不能想当然的认为这个值设置的越小越好,你要知道Parallel Scavenge是如何做到控制停顿时间的?实际上就是简单的增加垃圾回收频率而已,也就是说你设置的停顿时间越短,垃圾回收的频率就会越频繁,比如:原来30秒一次垃圾回收,一次停顿2秒,现在由于设置的停顿时间为1秒,所以必须10秒执行一次垃圾回收,虽然停顿时间短了,但是吞吐量也低了。

-XX:GCTimeRatio

值为大于0小于100的整数,也就是垃圾收集时间占总时间的 比率,相当于吞吐量的倒数。比如把此参数设置为19,那允许的最大垃圾收集时间就占总时间的5% (即1/(1+19)),默认值为99,即允许最大1%(即1/(1+99))的垃圾收集时间。

-XX:+UseAdaptiveSizePolicy

这个参数打开后,就不需要手工指定新生代的大小(-Xmn)、Eden与Survivor区的比例(-XX:SurvivorRatio)、晋升老年代对象年龄(-XX:PretenureSizeThreshold)等细节参数了,虚拟机会根据当前系统的运行情况收集性能监控信息,动态调整这些参数以提供最合适的停顿时间或者最大的吞吐量,这种调节方式称为GC自适应的调节策略(GC Ergonomics)。只需要把基本的内存数据设置好(如-Xmx设置最大堆),然后使用MaxGCPauseMillis参数(更关注最大停顿时间)或GCTimeRatio(更关注吞吐量)参数给虚拟机设立一个优化目标,那具体细节参数的调节工作就由虚拟机完成了。

  • 在 JDK 1.8 中,如果使用 CMS,无论 UseAdaptiveSizePolicy 如何设置,都会将 UseAdaptiveSizePolicy 设置为 false;不过不同版本的JDK存在差异;
  • UseAdaptiveSizePolicy不要和SurvivorRatio参数显示设置搭配使用,一起使用会导致参数失效;
  • 由于AdaptiveSizePolicy会动态调整 Eden、Survivor 的大小,有些情况存在Survivor 被自动调为很小,比如十几MB甚至几MB的可能,这个时候YGC回收掉 Eden区后,还存活的对象进入Survivor 装不下,就会直接晋升到老年代,导致老年代占用空间逐渐增加,从而触发FULL GC,如果一次FULL GC的耗时很长(比如到达几百毫秒),那么在要求高响应的系统就是不可取的。

附:对于面向外部的大流量、低延迟系统,不建议启用此参数,建议关闭该参数。

Parallel Scavenge为什么不能与CMS使用

Parallel Scavenge没有使用通用的那个GC框架,所以不能跟使用了那个框架的CMS搭配使用。就这么简单,不是什么算法/技术上的不兼容,纯粹是人为造成的。 

Parallel Scavenge和ParNew抽象来说是同一思路的GC,而后者可以跟CMS搭配使用。

老年代回收器

并发GC(CMS)与并行GC(Parallel Compacting)的区别?

  • 并行(Parallel):多条垃圾收集线程并行工作,而用户线程仍处于等待状态。
  • 并发(Concurrent):垃圾收集线程与用户线程一段时间内同时工作(交替执行)

2

评论0

请先

显示验证码
没有账号?注册  忘记密码?

社交账号快速登录