JVM性能优化(2)

JVM性能优化(二)--垃圾回收

  • 一、垃圾回收
  • 二、 如何确定对象为垃圾
    • 1、引用计数法
    • 2、可达性分析
  • 三、对象清除算法
  • 四、垃圾收集器
    • Serial收集器
    • ParNew收集器
    • Parallel Scavenge收集器
    • Serial Old 收集器
    • Parallel Old收集器
    • CMS收集器
    • G1收集器
  • 五、垃圾收集器分类及适用场景
  • 六、吞吐量、停顿时间
  • 七、垃圾收集器选择
  • 八、常用命令&常用工具
    • 命令
    • 工具
  • 九、性能优化
  • 十、常用调优参数

一、垃圾回收

在java中,不需要手动的去释放一个对象的内存的,而是由虚拟机自动执行。在JVM中,有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空闲或者当前堆内存不足时,才会触发执行,扫面那些没有被任何引用的对象,并将它们添加到要回收的集合中,进行回收。

二、 如何确定对象为垃圾

1、引用计数法

当一个对象没有任何指向其的引用,则该对象为垃圾。
弊端:互相引用的对象,永远不能判定为垃圾。

2、可达性分析

使用GC Root对对象进行向下寻找,看对象是否可达。
可以作为GC Root:
类加载器、Thread、虚拟机栈中的本地变量表、static成员等。

三、对象清除算法

  • 标记-清除
  • 标记-整理
  • 标记-复制

四、垃圾收集器

JVM性能优化(2)_第1张图片

Serial收集器

  • 单线程
  • 标记-复制算法
  • 新生代
  • 暂停应用程序线程

ParNew收集器

  • Serial收集器的多线程版本
  • 标记-复制算法
  • 新生代
  • 暂停应用程序线程

Parallel Scavenge收集器

  • 多线程并行
  • 标记-复制
  • 新生代
  • 类似ParNew收集器
  • 更关注系统的吞吐量

Serial Old 收集器

  • 类似Serial收集器
  • 单线程
  • 标记-整理
  • 老年代

Parallel Old收集器

  • 多线程并行
  • 标记-标记整理
  • 老年代
  • 吞吐量优先

CMS收集器

JVM性能优化(2)_第2张图片

  • 并发收集器,四个阶段
  • 标记-清除算法
  • 老年代
  • 更加关注减少垃圾收集时间

G1收集器

JVM性能优化(2)_第3张图片

  • 并行并发
  • 标记-整理 不存在空间碎片
  • 将堆内存空间划分为独立的Region
  • 优先清理垃圾多的区域
  • 可以自定义 GC 停顿时间 -XX:MaxGCPauseMillis=200
  • JDK7开始使用、JDK8成熟、JDK9默认新老收集器

五、垃圾收集器分类及适用场景

  • 串行 内存较小的设备
  • 并行 后台处理,高吞吐量
  • 并行 web场景,停顿时间短

六、吞吐量、停顿时间

性能调优关注的指标

  • 吞吐量=执行用户代码时间/执行用户代码时间+垃圾收集时间
  • 停顿时间=垃圾收集器执行垃圾回收的时间

七、垃圾收集器选择

  • 优先调整堆内存大小,默认垃圾收集器
  • 内存小于100M ,单线程收集器
  • 允许停顿时间超过1S,并行收集器或默认
  • 要求停顿时间小于1S,并发收集器
  • G1: 存活对象占堆的50%以上,垃圾回收时间长

八、常用命令&常用工具

命令

  • jinfo 查看调整JVM参数信息
  • jstat 查看类装载信息
  • jstack 查看线程堆栈信息,排查死锁线程
  • jmap 查看堆内存信息,dump堆内存 堆内存溢出,自动生成dump文件命令:-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof

工具

  • jconsole
  • jvisualvm
  • MAP 分析堆内存dump文件用
  • GC日志 https://gceasy.io

九、性能优化

JVM性能优化(2)_第4张图片

十、常用调优参数

  • 设定堆内存大小
    -Xmx:堆内存最大限制。

  • 设定新生大小。 新生代不宜太小,否则会有大量对象涌入老年代
    -XX:NewSize:新生代大小
    -XX:NewRatio 新生代和老生代占比
    -XX:SurvivorRatio:伊甸园空间和幸存者空间的占比

  • 设定垃圾回收器 年轻代用 -XX:+UseParNewGC 年老代用-XX:+UseConcMarkSweepGC

  • 打印

-XX:+PrintGC:输出形式:[GC 118250K->113543K(130112K), 0.0094143 secs] [Full GC 121376K->10414K(130112K), 0.0650971 secs] 
-XX:+PrintGCDetails:输出形式:[GC [DefNew: 8614K->781K(9088K), 0.0123035 secs] 118250K->113543K(130112K), 0.0124633 secs] [GC [DefNew: 8614K->8614K(9088K), 0.0000665 secs][Tenured: 112761K->10414K(121024K), 0.0433488 secs] 121376K->10414K(130112K), 0.0436268 secs] 
-XX:+PrintGCTimeStamps -XX:+PrintGC:PrintGCTimeStamps可与上面两个混合使用,输出形式:11.851: [GC 98328K->93620K(130112K), 0.0082960 secs] 
-XX:+PrintGCApplicationConcurrentTime:打印每次垃圾回收前,程序未中断的执行时间。可与上面混合使用。输出形式:Application time: 0.5291524 seconds 
-XX:+PrintGCApplicationStoppedTime:打印垃圾回收期间程序暂停的时间。可与上面混合使用。输出形式:Total time for which application threads were stopped: 0.0468229 seconds 
-XX:PrintHeapAtGC: 打印GC前后的详细堆栈信息 
-Xloggc:filename:与上面几个配合使用,把相关日志信息记录到文件以便分析 
-verbose:class 监视加载的类的情况 
-verbose:gc 在虚拟机发生内存回收时在输出设备显示信息 
-verbose:jni 输出native方法调用的相关情况,一般用于诊断jni调用错误信息 

你可能感兴趣的:(JVM性能优化)