千千梦丶琪 发表于 2025-4-10 13:17:41

走进底层 - JVM工作原理入门指南

走进底层 - JVM工作原理入门指南

   Java 之所以可以大概实现“一次编写,到处运行”(Write Once, Run Anywhere, WORA),核心在于 Java 虚拟机(JVM, Java Virtual Machine)。JVM 是 Java 程序的运行情况,负责将 Java 字节码(.class 文件)转换成呆板码并执行。
本文将从 JVM 的基本结构、内存管理、类加载机制 和 垃圾接纳(GC) 四个方面,初步了解 JVM 的工作原理。
1. JVM 的基本结构

JVM 主要由以下几个核心部分构成:

[*]类加载子系统

[*]负责加载 .class 文件到内存,并天生对应的 Class 对象。

[*]运行时数据区

[*]包括 方法区(Method Area)、堆(Heap)、虚拟机栈(VM Stack)、本地方法栈(Native Method Stack) 和 程序计数器(Program Counter Register)。

[*]执行引擎

[*]负责执行字节码,包括 解释器(Interpreter) 和 即时编译器(JIT Compiler)。

[*]本地方法接口

[*]用于调用 C/C++ 编写的本地库。
https://i-blog.csdnimg.cn/direct/5b04c5e2e3c54e3fb092a9e0f60e70cb.png

2. 运行时数据区(内存模型)

JVM 的内存主要分为以下几个部分:
(1) 方法区(Method Area)



[*]用于存储已被加载的类信息、常量、静态变量、即时编译器编译后的代码缓存等数据。在 JDK 8 及之后的版本中,方法区利用元空间(Metaspace)来实现,元空间并不在堆内存中,而是利用本地内存。常量池是方法区的一部分,它存储了各种常量,包括字符串常量、基本数据范例常量等
(2) 堆



[*]全部对象实例和数组都在堆上分配,是垃圾接纳(GC)的主要区域,也是jvm的最大区域。
[*]分为:

[*]新生代:存放新创建的对象,分为 Eden 区 和 Survivor 区(S0、S1)。
[*]老年代:存放恒久存活的对象。
[*]元空间(JDK 8+):取代永久代,存储类元数据。

(3) 虚拟机栈



[*]每个线程在运行时都会有一个对应的 Java 虚拟机栈。它由一个个栈帧(Stack Frame)构成,栈帧用于存储局部变量表、操纵数栈、动态链接、方法出口等信息。当一个方法被调用时,就会创建一个新的栈帧并压入栈顶,方法执行完毕后,栈帧就会从栈顶弹出。局部变量表用于存储方法中的局部变量,包括基本数据范例和对象引用。操纵数栈则用于方法执行过程中的运算操纵
(4) 本地方法栈



[*]类似于虚拟机栈,但用于执行 本地方法(如 C/C++ 代码)。
(5) 程序计数器



[*]可以理解为一个指针,它记载了当前线程正在执行的字节码指令的地址。如果当前线程正在执行一个 Java 方法,那么程序计数器中保存的就是正在执行的字节码指令的地址;如果正在执行的是本地方法(Native Method),那么程序计数器的值就是未界说的。由于 Java 是多线程的,每个线程都有本身独立的程序计数器,这样当线程切换时,就可以大概规复到正确的执行位置
3. 类加载机制

JVM 加载 .class 文件的过程分为 加载、连接、初始化 三个阶段:
(1) 加载(Loading)



[*]通过 类加载器(ClassLoader) 查找 .class 文件并加载到内存。
[*]类加载器分类:

[*]Bootstrap ClassLoader(启动类加载器):加载 JAVA_HOME/lib 下的核心类(如 java.lang.*)。
[*]Extension ClassLoader(扩展类加载器):加载 JAVA_HOME/lib/ext 下的扩展类。
[*]Application ClassLoader(应用类加载器):加载用户类路径(classpath)下的类。
[*]自界说 ClassLoader:用户可继承 ClassLoader 实现本身的加载逻辑。一样平常用于服务器的加载器(因为同一个类名不会被反复加载,因此为了防止同类名不同数据的类被省略,必要自界说一个类实现多个对象)

(2) 连接



[*]验证:检查字节码是否符合 JVM 规范。
[*]准备:为静态变量分配内存并赋默认值(如 int 默认 0)
[*]剖析:将符号引用(如 java.lang.Object)替换为直接引用(内存地址),也就是类名等字符转换为地址
(3) 初始化



[*]执行静态代码块(static {})和静态变量赋值。
[*]采用 双亲委派机制 避免重复加载类。
4. 垃圾接纳(GC)

JVM 主动管理内存,通过 垃圾接纳器 接纳不再利用的对象。
(1) 怎样判断对象可接纳?



[*]引用计数法(Python 利用):对象被引用时计数+1,为 0 时接纳(但 Java 不采用,因为无法解决循环引用问题)。
[*]可达性分析:从 GC Roots(如虚拟机栈、静态变量、本地方法栈引用的对象)出发,标记全部可达对象,不可达的视为垃圾。
(2) 垃圾接纳算法



[*]标记-清除:标记垃圾对象后直接清除,但会产生内存碎片。
[*]复制:将存活对象复制到另一块内存(用于 新生代,如 Eden → Survivor)。
[*]标记整理:标记存活对象后整理内存(用于 老年代)。
5. 执行引擎

JVM 执行字节码的方式:

[*]解释执行:逐行解释字节码,执行速度较慢。
[*]即时编译(JIT):将热门代码(HotSpot)编译成呆板码,提高执行速度
总结

构成部分核心功能类加载子系统加载 .class 文件到内存运行时数据区存储类信息、对象、方法调用等执行引擎解释或编译执行字节码垃圾接纳(GC)主动接纳无用对象,释放内存 JVM 是 Java 生态的核心,理解其工作原理有助于优化代码、排查内存走漏(OOM)和提升性能。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 走进底层 - JVM工作原理入门指南