浅谈 JVM 调优

基础知识

JVM 是 Java 虚拟机的简称,是一个虚拟出来的计算机,是一种规范。

JVM内存模型

如下图所示,主要由如下几个部分组成:

  • :所有对象都在堆上分配,也叫 Java 堆、GC 堆。
  • 方法区:存储类信息、常量、静态变量、即时编译后的代码。
  • 本地方法栈(线程隔离):存储局部变量表、操作栈、动态链接、方法出口,对象指针。
  • 虚拟机栈(线程隔离):为虚拟机使用到的Native 方法服务。
  • 程序计数器(线程隔离):当前线程所执行的字节码的行号指示器。指向下一条要执行的指令。

JVM内存模型

内存回收过程

从 JVM 内存模型我们知道,所有对象都在 Java 堆上分配,因此 Java 堆也是垃圾收集器管理的主要区域,也叫 GC 堆。按照分代法,划分为:新生代、老年代。

进一步划分的目的是更好地回收内存,或者更快地分配内存。

  • 新生代
    • Eden
    • From Survivor0
    • To Survivor1
  • 老年代

Java 堆

GC(Garbage Collection):即垃圾收集,Java 通过 JVM 自动内存管理。GC线程执行时,会暂停其他应用程序线程。

GC 分类:

  • Young GC(Minor GC):Eden 内存区域占满导致的垃圾回收;
  • Old GC(Major GC):老年代 内存区域占满导致的垃圾回收;
  • Full GC:新生代、老年代的全体内存空间的垃圾回收;停顿时间长。

垃圾收集器

垃圾收集算法(方法论):标记-清除;标记-复制;标记-整理;分代收集;
垃圾收集器(具体实现):Serial、Serial Old、ParNew、Parallel Scavenge、Parallel Old、CMS、G1、ZGC

常见垃圾收集器对比

GC流程

常见 JVM 参数

调优思路

调优时机

性能调优,可分为:架构调优、代码调优、JVM调优、数据库调优、操作系统调优。JVM 调优是最后调优手段。

当出现如下情况时,才考虑进行 JVM 调优:

  • Heap 内存(老年代)持续上涨达到设置的最大内存值;
  • Full GC 次数频繁;
  • GC 停顿时间过长(超过1秒);
  • 应用出现 OutOfMemory 等内存异常;
  • 应用中有使用本地缓存且占用大量内存空间;
  • 系统吞吐量与响应性能不高或下降。

调优原则

调优目标

三大指标

  • 吞吐量:应用程序线程用时占程序总用时的比例;
  • 暂停时间:执行垃圾收集时,程序的工作线程被暂停的时间;
  • 内存占用:java堆区所占的内存大小;

调优步骤

常用工具

JDK 命令行工具

VisualVM

扩展

如何排查 OOM 的问题?

  • 增加两个参数 -XX:+HeapDumpOnOutOfMemoryError -
  • XX:HeapDumpPath=/tmp/heapdump.hprof,当 OOM 发生时自动 dump 堆内存信息到指定目录。
  • 同时 jstat 查看监控 JVM 的内存和 GC 情况,先观察问题大概出在什么区域。
  • 使用 MAT 工具载入到 dump 文件,分析大对象的占用情况,比如 HashMap 做缓存未清理,时间长了就会内存溢出,可以把改为弱引用。

调优案例【WIP】

排障案例【WIP】