Skip to content

☕ JVM 核心知识


I. 内存模型 (Runtime Data Areas)

1. 区域划分

JVM 在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域:

  • 线程私有

    • 程序计数器 (Program Counter Register):当前线程所执行的字节码的行号指示器,是唯一一个不会出现 OOM 的区域.
    • 虚拟机栈 (VM Stack):描述 Java 方法执行的内存模型,每个方法执行时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息.
    • 本地方法栈 (Native Method Stack):与虚拟机栈类似,不过是为 Native 方法服务.
  • 线程共享

    • 堆 (Heap):JVM 管理的最大一块内存,存放对象实例,是 GC 的主要区域.
    • 方法区 (Method Area):存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据 (JDK 8 后由元空间 Metaspace 实现,使用本地内存).

2. 堆内存分布

  • 新生代 (Young Generation)
    • Eden 区:新对象主要分配在 Eden 区.
    • Survivor 区 (S0, S1):存活对象在 S0/S1 之间复制,默认比例 Eden:S0:S1 = 8:1:1.
  • 老年代 (Old Generation):存放生命周期较长的对象.

II. 垃圾回收 (GC)

1. 如何判断对象已死?

  • 引用计数法:对象被引用一次加1,引用失效减1。无法解决循环引用问题.
  • 可达性分析算法 (主流):从 GC Roots (如栈中引用的对象、静态变量引用的对象) 出发,通过引用链向下搜索,不可达的对象即可回收.

2. 常见的 GC 算法

  • 标记-清除 (Mark-Sweep):标记出所有需要回收的对象,统一回收。缺点:内存碎片.
  • 标记-复制 (Mark-Copy):将内存分为两块,每次只用一块,将存活对象复制到另一块。优点:无碎片;缺点:内存利用率低 (用于新生代).
  • 标记-整理 (Mark-Compact):标记存活对象,将其向一端移动,清理掉边界以外的内存。优点:无碎片 (用于老年代).

3. 说明一下 CMS 和 G1

  • CMS (Concurrent Mark Sweep)

    • 以获取最短回收停顿时间为目标.
    • 基于“标记-清除”算法.
    • 过程:初始标记(STW) -> 并发标记 -> 重新标记(STW) -> 并发清除.
    • 缺点:对 CPU 敏感、产生内存碎片.
  • G1 (Garbage First)

    • 面向服务端应用,可预测停顿.
    • 将堆划分为多个大小相等的 Region.
    • 整体看是“标记-整理”,局部看是“标记-复制”,不会产生内存碎片.
    • 适合大内存机器,JDK 9 默认收集器.

III. 类加载机制

1. 类加载过程

  1. 加载 (Loading):通过全类名获取二进制字节流,将静态存储结构转化为方法区的运行时数据结构.
  2. 链接 (Linking)
    • 验证:确保字节码符合规范.
    • 准备:为静态变量分配内存并设置零值.
    • 解析:将常量池内的符号引用替换为直接引用.
  3. 初始化 (Initialization):执行类构造器 <clinit> 方法 (静态代码块赋值).

2. 双亲委派模型 (Dual Parent Delegation)

  • 定义:当一个类加载器收到类加载请求时,首先委托给父类加载器去完成,父加载器无法加载时才自己尝试加载.
  • 好处:保证核心类库 (如 java.lang.Object) 的安全性,避免用户自定义类覆盖核心类.
  • 打破场景:JDBC (通过 SPI 机制)、Tomcat (Web 应用隔离).

IV. 常见 JVM 参数与排查

1. 常用参数

  • -Xms / -Xmx:设置堆的初始大小和最大大小 (通常设置为相同,避免动态扩容抖动).
  • -Xmn:设置新生代大小.
  • -XX:MetaspaceSize:设置元空间初始大小.
  • -XX:+PrintGCDetails:打印 GC 详细日志.
  • -XX:+HeapDumpOnOutOfMemoryError:OOM 时自动 Dump 堆内存.

2. 线上排查工具

  • jps:查看 Java 进程状态.
  • jstat:监视虚拟机各种运行状态信息 (GC 情况等).
  • jinfo:实时查看和调整虚拟机各项参数.
  • jmap:生成堆转储快照 (dump 文件).
  • jstack:生成虚拟机当前时刻的线程快照 (排查死锁、CPU 飙高).
  • Arthas:阿里开源的 Java 诊断工具 (推荐).