JVM——结构简述

5 阅读4分钟

JVM 篇

1 什么是JVM

JVM 是 Java Virtual Machine 的缩写,是 Java 能够实现跨平台的根本原因,我们编写的 Java 代码,终究会被编译为字节码文件,然后运行于 JVM 虚拟机上, JVM 拥有多个平台的支持的版本,所以Java 能够跨平台(操作系统和不同的 CPU 架构)的原因是 JVM 拥有多个平台的版本的实现。

2 JVM 的组成

JVM 可以简单分为四个部分:

  1. 类加载器子系统
  2. 运行时数据区
  3. 执行引擎
  4. 本地方法接口

下面简单阐述下这四个部分的主要构成与功能:

  1. 类加载器子系统(Class Loader Subsystem)
  • 作用:负责将字节码文件(.class)加载到 JVM 中,并完成验证、准备、解析、初始化等操作,最终形成可被 JVM 直接使用的类数据。

  • 核心流程

    • 加载:通过类的全限定名获取字节流;
    • 验证:确保字节码符合 JVM 规范(安全性校验);
    • 准备:为类的静态变量分配内存并设置默认值;
    • 解析:将符号引用转换为直接引用(如方法 / 字段的内存地址);
    • 初始化:执行类构造器<clinit>()方法(初始化静态变量和静态代码块)。
  • 特点:采用 “双亲委派模型”,避免类的重复加载和安全问题。

  1. 运行时数据区(Runtime Data Area)
  • 作用:这是 JVM 存储数据的区域,也是之前提到的 “内存区域” 的总称,是执行引擎运行的基础。

  • 组成(按 Java 虚拟机规范):

    • 程序计数器:记录当前线程执行的字节码指令地址(线程私有);

    • 虚拟机栈:存储方法执行时的栈帧(局部变量、操作数栈等,线程私有);

    • 本地方法栈:类似虚拟机栈,但为本地方法(如 C/C++ 方法)服务;

    • 堆:存储对象实例和数组(线程共享,GC 主要区域);

    • 方法区:存储类信息、常量、静态变量等(线程共享,JDK 8 后为元空间)。

  1. 执行引擎(Execution Engine)
  • 作用:是 JVM 的 “心脏”,负责将字节码指令翻译为机器码并执行,是连接字节码和底层硬件的核心。

  • 执行方式

    • 解释执行:逐条翻译字节码为机器码并立即执行(启动快,适合短程序);
    • 即时编译(JIT 编译):将 “热点代码”(频繁执行的代码)编译为本地机器码并缓存,后续直接执行机器码(执行效率高,适合长运行程序);
    • 混合模式:JVM 默认采用 “解释 + JIT” 混合执行,兼顾启动速度和运行效率。
  • 核心组件:包括解释器、JIT 编译器(如 HotSpot 的 C1/C2 编译器)、垃圾回收器接口(配合堆内存管理)等。

  1. 本地方法接口(Native Method Interface, JNI)
  • 作用:作为 JVM 与本地代码(如 C/C++)的桥梁,允许 Java 代码调用本地方法(通过native关键字声明),扩展 JVM 的功能(如操作硬件、调用系统 API 等)。

  • 配合组件:通常与 “本地方法栈” 协同工作,存储本地方法执行时的状态。

各个部分之间的协同关系:

  1. 类加载器将.class 文件加载到运行时数据区;
  2. 执行引擎从运行时数据区读取字节码,通过解释或编译方式执行;
  3. 执行过程中如需调用本地方法,通过 JNI 接口调用,使用本地方法栈存储状态;
  4. 运行时数据区的内存由垃圾回收器(属于执行引擎的辅助组件)自动管理,释放无用对象内存。

3 常见面试问题

类加载

类加载过程?

类加载机制?

双亲委派机制的优点?

什么时候需要打破双亲委派机制?

String 类的双亲委派机制可以打破吗?

运行时数据区

构成?

哪些会 OOM?

哪些是线程共享的?

JVM 不是自动回收垃圾吗,为什么还会 OOM?

垃圾回收

垃圾回收算法?

垃圾回收器?

什么时候会频繁触发 full GC?

G1?

CMS?

zgc?

生产问题

此部分参考 JavaGuide 的介绍,链接为:

  1. javaguide.cn/java/jvm/jd…
  2. javaguide.cn/java/jvm/jv…