JVM

概述

JVM(Java Virtual Machine)是 Java 程序运行的虚拟机,负责将字节码翻译成机器码执行,提供跨平台能力和自动内存管理。

内存结构

运行时数据区

区域 线程共享 说明
堆(Heap) 存放对象实例,GC 主要管理区域
方法区(Method Area) 存放类信息、常量、静态变量
虚拟机栈(VM Stack) 每个方法一个栈帧(局部变量表、操作数栈等)
本地方法栈(Native Stack) 为 Native 方法服务
程序计数器(PC Register) 记录当前线程执行的字节码行号

JDK 8 内存模型变化

  • 永久代(PermGen)→ 元空间(Metaspace)
  • 元空间使用本地内存,不再受 JVM 堆大小限制

垃圾回收(GC)

如何判断对象可回收

  • 引用计数法:循环引用问题
  • 可达性分析:从 GC Roots 出发,不可达的对象可回收

GC Roots 包括

  • 虚拟机栈中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈中 JNI 引用的对象

垃圾回收算法

  • 标记-清除:产生碎片
  • 标记-整理:移动对象,无碎片但开销大
  • 复制算法:两块区域来回复制,适合新生代
  • 分代收集:新生代用复制,老年代用标记-整理

常见垃圾回收器

| 回收器 | 算法 | 适用区域 | 特点 | |——–|——|———-|——| | Serial | 复制 | 新生代 | 单线程,Client 模式默认 | | ParNew | 复制 | 新生代 | Serial 多线程版 | | Parallel Scavenge | 复制 | 新生代 | 吞吐量优先 | | CMS | 标记-清除 | 老年代 | 低延迟,有碎片问题 | | G1 | 分区收集 | 全堆 | JDK 9 默认,可预测停顿 | | ZGC | 着色指针 | 全堆 | 超低延迟(<10ms) |

类加载机制

类加载过程

  1. 加载:读取 class 文件,生成 Class 对象
  2. 验证:校验字节码格式和安全性
  3. 准备:为静态变量分配内存并赋默认值
  4. 解析:将常量池符号引用替换为直接引用
  5. 初始化:执行 <clinit>() 方法

双亲委派模型

  • 自底向上检查是否已加载,自顶向下尝试加载
  • Bootstrap → Extension → Application ClassLoader
  • 可自定义 ClassLoader 打破双亲委派

JVM 调优常用参数

# 堆大小
-Xms512m -Xmx2g

# 新生代大小
-Xmn256m

# 元空间大小
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m

# GC 日志
-Xlog:gc*:file=gc.log

# 使用 G1 收集器
-XX:+UseG1GC

常见面试题

  1. JVM 内存模型是怎样的?
  2. 什么是双亲委派模型?为什么需要?
  3. CMS 和 G1 的区别?
  4. 什么情况下会发生 OOM?如何排查?
  5. JVM 调优的常见手段?

参考资料

  • 《深入理解 Java 虚拟机》- 周志明