JVM收集器种类和GC参数

一、GC收集器的种类

1. 串行收集器(最古老,最稳定)

  1. 效率高
  2. 可能产生较长时间的停顿
  3. 使用方法:-XX:+UseSerialGC
    1. 新生代和老年代使用串行回收器
    2. 新生代复制算法
    3. 老年代使用标记压缩算法

JVM收集器种类和GC参数_第1张图片

[GC (Allocation Failure) [DefNew: 494K->28K(1856K), 0.0007607 secs][Tenured: 2460K->2088K(4096K), 0.0185495 secs] 2891K->2088K(5952K), [Metaspace: 8175K->8175K(1056768K)], 0.0199235 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 

[Full GC (Allocation Failure) [Tenured: 2088K->1865K(13696K), 0.0050507 secs] 2088K->1865K(15616K), [Metaspace: 8175K->8175K(1056768K)], 0.0051147 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

2. 并行收集器

  1. ParNew收集器
    1. -XX:+UseParNewGC
    2. 新生代并行,老年代串行
  1. Serial收集器新生代的并行版本
  2. 采用复制算法
  3. 多线程,需要多核支持
  4. -XX:ParallelGCThreads 限制线程数量,最好与电脑的核数相等

JVM收集器种类和GC参数_第2张图片

[GC (Allocation Failure) [ParNew: 534K->80K(1856K), 0.0005378 secs][Tenured: 2991K->2404K(4096K), 0.0255715 secs] 3445K->2404K(5952K), [Metaspace: 8167K->8167K(1056768K)], 0.0264774 secs] [Times: user=0.02 sys=0.00, real=0.03 secs] 

[Full GC (Allocation Failure) [Tenured: 2404K->2104K(13696K), 0.0092037 secs] 2404K->2104K(15616K), [Metaspace: 8167K->8167K(1056768K)], 0.0092783 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 

Parallel收集器

  1. 类似ParNew
  2. 新生代复制算法,老年代 标记-压缩
  3. 更加关注吞吐量
  4. -XX:+UseParallelGC 使用Parallel收集器+ 老年代串行
  5. -XX:+UseParallelOldGC使用Parallel收集器+ 并行老年代

JVM收集器种类和GC参数_第3张图片

[GC (Allocation Failure) [PSYoungGen: 384K->0K(5120K)] 3243K->2954K(18944K), 0.0005837 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 

[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(5120K)] [ParOldGen: 2954K->2015K(4096K)] 2954K->2015K(9216K), [Metaspace: 8165K->8165K(1056768K)], 0.0346569 secs] [Times: user=0.19 sys=0.00, real=0.03 secs] 
  1. -XX:MaxGCPauseMills
    1. 最大停顿时间,单位毫秒
    2. GC尽力保回收时间不超过设定值
  2. -XX:GCTimeRatio
    1. 0-100的取值范围
    2. 垃圾收集时间占总时间的比
    3. 默认99,即最大允许1%时间做GC
  3. 补充说明:这两个参数是矛盾的。因为停顿时间和吞吐量不可能同时调优,必须按实际情况进行取舍
  1. CMS收集器(Concurrent Mark Sweep 并发标记清除)
  1. 与用户线程一起执行
  2. -XX:+UseConcMarkSweepGC使用并发标记清除收集器

JVM收集器种类和GC参数_第4张图片
3. 如上图所示,CMS运行过程比较复杂,着重实现了标记的过程,可分为
1. 初始标记
1. 根可以直接关联到的对象
2. 速度快
2. 并发标记(和用户线程一起)
1. 主要标记过程,标记全部对象
3. 重新标记
1. 由于并发标记时,用户线程依然运行,因此在正式清理前,再做修正
4. 并发清除(和用户线程一起)
1. 基于标记结果,直接清理对象

[GC (CMS Initial Mark) [1 CMS-initial-mark: 2125K(4096K)] 2362K(5952K), 0.0013094 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[CMS-concurrent-mark-start]
[CMS-concurrent-mark: 0.002/0.002 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[CMS-concurrent-preclean-start]
[CMS-concurrent-preclean: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (CMS Final Remark) [YG occupancy: 517 K (1856 K)][Rescan (parallel) , 0.0007277 secs][weak refs processing, 0.0000171 secs][class unloading, 0.0006060 secs][scrub symbol table, 0.0005643 secs][scrub string table, 0.0001149 secs][1 CMS-remark: 2125K(4096K)] 2643K(5952K), 0.0020999 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[CMS-concurrent-sweep-start]
[CMS-concurrent-sweep: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[CMS-concurrent-reset-start]
[CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 

  1. 特点
    1. 尽可能降低停顿
    2. 会影响系统整体吞吐量和性能,比如,在用户线程运行过程中,分一半CPU去做GC,系统性能在GC阶段,反应速度就下降一半
    3. 清理不彻底,因为在清理阶段,用户线程还在运行,会产生新的垃圾,无法清理
    4. 因为和用户线程一起运行,不能在空间快满时再清理
      1. -XX:CMSInitiatingOccupancyFraction设置触发GC的阈值
      2. 如果不幸内存预留空间不够,就会引起concurrent mode failure
    5. 使用串行收集器作为后备
    6. -XX:+ UseCMSCompactAtFullCollectionFull GC后,进行一次整,整理过程是独占的,会引起停顿时间变长
    7. -XX:+CMSFullGCsBeforeCompaction 设置进行几次Full GC后,进行一次碎片整理
    8. -XX:ParallelCMSThreads设定CMS的线程数量,线程不是越多越快,需要按需设计,最好和电脑的核数一致

二、参数汇总

-XX:+UseSerialGC:在新生代和老年代使用串行收集器
-XX:SurvivorRatio:设置eden区大小和survivior区大小的比例
-XX:NewRatio:新生代和老年代的比
-XX:+UseParNewGC:在新生代使用并行收集器
-XX:+UseParallelGC :新生代使用并行回收收集器
-XX:+UseParallelOldGC:老年代使用并行回收收集器
-XX:ParallelGCThreads:设置用于垃圾回收的线程数
-XX:+UseConcMarkSweepGC:新生代使用并行收集器,老年代使用CMS+串行收集器
-XX:ParallelCMSThreads:设定CMS的线程数量
-XX:CMSInitiatingOccupancyFraction:设置CMS收集器在老年代空间被使用多少后触发
-XX:+UseCMSCompactAtFullCollection:设置CMS收集器在完成垃圾收集后是否要进行一次内存碎片的整理
-XX:CMSFullGCsBeforeCompaction:设定进行多少次CMS垃圾回收后,进行一次内存压缩
-XX:+CMSClassUnloadingEnabled:允许对类元数据进行回收
-XX:CMSInitiatingPermOccupancyFraction:当永久区占用率达到这一百分比时,启动CMS回收
-XX:UseCMSInitiatingOccupancyOnly:表示只在到达阀值的时候,才进行CMS回收

三、调优思路

为减轻GC压力,我们需要注意些什么?

  1. 软件架构设计
  1. 代码编写
  1. 堆空间合理分配
  1. JDK的选择(升级JDK可能会带来额外的性能提升)

四、总结

  1. 性能的根本在应用
  2. GC参数属于微调
  3. 设置不合理,会影响性能,产生大的延时

你可能感兴趣的:(jvm,gc收集器种类,gc参数)