VM内部结构
对于jvm来说他的内部结构主要分成三个部分,分别是类加载阶段,运行时数据区,以及垃圾回收区域,类加载我们放到之后来总结,今天先复习一下类运行区域
首先这个区域主要是分成如下几个部分
下面举个例子来解释一下
public class Example {
// 静态变量
static int staticVar = 10;
// 实例变量
int instanceVar;
public static void main(String[] args) {
// 局部变量
int localVar = 20;
// 创建对象
Example example = new Example();
example.instanceVar = 30;
// 调用方法
example.addAndPrint(localVar, 5);
}
// 两个数相加的方法
public void addAndPrint(int a, int b) {
int sum = a + b;
System.out.println("Sum: " + sum);
}
}
1. 方法区(Method Area)
方法区存储类的结构信息、常量池、字段、方法等。
- 类结构:
Example.class
类的字节码、常量池、字段、方法等都存储在方法区。- 常量池:包含常量
staticVar = 10
(常量池是类的静态数据部分)。 - 方法信息:存储
main
方法、addAndPrint
方法的字节码。 - 字段信息:存储类中的静态字段
staticVar
和实例字段instanceVar
。
- 常量池:包含常量
2. 堆区(Heap)
堆区存储所有通过 new
关键字创建的对象实例和数组。
- 对象实例:当执行到
Example example = new Example();
时,Example
类的一个实例会被分配到堆区。这个实例包含一个instanceVar
字段,它的初始值是0
。 - 对象属性:
example.instanceVar = 30;
时,实例对象的instanceVar
被更新为30
。
3. 栈区(Stack)
栈区存储每个方法的局部变量和方法调用的参数、返回地址等。每当一个方法调用时,都会为该方法分配一个栈帧。
main
方法的栈帧:- 存储局部变量
localVar = 20
。 - 存储方法参数
args
,即String[] args
(虽然我们没有用到,但它也会存在于栈帧中)。 - 存储局部变量
example
,它指向堆区中创建的Example
对象。
- 存储局部变量
addAndPrint
方法的栈帧:addAndPrint
方法有两个参数a
和b
,其中a = localVar = 20
和b = 5
,它们都存储在addAndPrint
方法的栈帧中。- 存储局部变量
sum
,用于存储两个数相加的结果。
4. 程序计数器(PC Register)
每个线程有一个程序计数器(PC),它保存当前线程正在执行的字节码指令的地址。对于每个线程,程序计数器是独立的。
main
方法的程序计数器:当执行main
方法时,程序计数器指向main
方法的字节码指令。指令顺序执行时,程序计数器会根据程序流程指向不同的代码行。addAndPrint
方法的程序计数器:当main
方法调用addAndPrint(localVar, 5)
时,程序计数器会切换到addAndPrint
方法,指向addAndPrint
方法的字节码指令。
5. 本地方法栈(Native Method Stack)
本地方法栈用于支持 Java 调用本地方法(如 C/C++)。在这个例子中,Java 程序没有调用本地方法,因此本地方法栈没有被使用。