Java基础 - JVM
什么是JVM
Java的理念是:Write Once, Run Anywhere。Java编译器把 Java 程序编译成“字节码”(.class 文件),字节码可以在所有平台运行,这是JAVA特性之一。字节码是 JVM 能理解的“中间语言”,JVM可以把字节码翻译成你的电脑能理解的机器指令。因此只需要在不同的机器上安装适配不同架构的JVM,就可以实现 Write Once, Run Anywhere。
JVM的功能
- 跨平台运行
- 内存管理:JAVA帮助开发者垃圾回收,分配内存
- 性能优化:即时编译器(Just-In-Time ,JIT ),将热点代码(频繁执行的代码段)编译成本地机器码,以提高程序的执行性能
- 安全性:异常处理,类加载时字节码验证,沙箱环境等
JVM的运行时数据区域
以JDK 1.7为例,
- 线程私有的:
- 程序计数器:当前线程执行的字节码位置
- Java 虚拟机栈:每个线程的JAVA方法的“方法调用栈”,包含栈帧
- 本地方法栈:给调用 C、C++ 等非 Java 方法(native 方法)用的栈
- 线程共享的
- 堆:用来存储所有 Java 对象实例,由垃圾回收器(GC)统一管理
- 方法区:用来存储类的元数据(类的信息、常量、静态变量、方法字节码等)。
类加载器
类加载器是指把类的字节码(通常是 .class 文件)加载到 JVM 的内存中,并生成相应的 Class 对象的工具。具体来说,类加载器把字节码(.class 文件)加载到 JVM 的方法区(Method Area)(Java 8 之后是 元空间(Metaspace)),然后在堆中创建一个 Class 对象来存储类的信息,方便反射操作。
类并不是一开始就全部加载。类加载器可以按需加载:当你第一次使用某个类时,它才去加载它。
1 |
|
根据以上的例子,类加载器执行过程:
- 加载:类加载器通过类的名字 Person 找到 Person.class 文件,将 .class 文件的字节码加载到 JVM,并在堆中生成一个代表这个类的 java.lang.Class 对象作为数据访问的入口
- 验证:检查字节码是否合法
- 准备:为静态变量(
List<String> list
)分配内存,并赋初始值 null(此时静态变量只是占位,还没初始化) - 解析:将符号引用替换为直接引用,比如将
System.out.println
方法名解析为真正的内存地址 - 初始化:执行静态代码块,给静态变量赋值(这里的list变量本身在方法区,指向的HashMap对象实例在堆里创建)
Class对象
1 |
|
比如,当JVM加载String类时,会执行Class cls = new Class(String);
在堆中创建Class对象。这个对象包含类名、包名、父类、实现的接口、所有方法、字段等对应class的所有信息。内存分布:
1 |
|
JAVA对象在内存中的结构
- 对象头
包含:
- 标记字段(Mark Word):指向哈希码(HashCode)、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程 ID等。
- 类型指针(Klass pointer):指向类的元数据,是一个在方法区的C++结构,与上文Class对象的klass_pointer指向的结构一样。
实例数据
对齐填充
Java基础 - JVM
https://thiefcat.github.io/2025/07/04/JAVA/java-jvm/