Java 内存模型
1、程序计数器
保存每个线程当前执行到的字节码的位置
program_counter[0] = 0x12DFED
program_counter[1] = 0xAb45EE
program_counter[2] = 0xFBED3A
2、Java 栈
每个线程都有一个独立的 Java 栈,栈由栈帧组成,每个方法都是一个栈帧;
栈帧的组成
1、操作数栈:operator_num_stack = stack()
2、运行时常量池:ref = rt_stack_pool()
3、方法返回地址
4、局部变量表
5、其他信息
局部变量表
1、保存栈帧中的所有局部变量
2、单位是 变量槽;
3、如果不是静态方法,局部变量表的第 0 位 是 this 指针,然后是参数列表,之后是方法内定义的局部变量
// 局部变量表 local_var_table = [this, a, b, c]
public void func(int a, int b) {
int c = 0;
}
3、Native 栈
描述的当前线程 native 方法的执行;
4、堆
存储对象实例本身和数组,所有线程共享一个堆区;
HopSpot 虚拟机中,堆区分为 年轻代 和 老年代,大部分对象都在年轻代创建。年轻代由一个较大的 伊甸园区 和 两个较小的 幸存者区 组成。
年轻代保存新创建的对象,幸存者区保存至少经历过一次 GC 的对象;
老年代保存久经 GC 还没有被回收的对象。
5、方法区
存储已经被虚拟机加载的 类名、方法、常量、静态变量、运行时常量池、即时编译器编译后的代码等数据。方法区 被 所有线程共享在一个逻辑分区,逻辑上保持独立。
HotSpot 虚拟机中,永久代 放在 方法区中,Java 8后,永久代放在 元空间中,使用的不是虚拟机内存,而是本地内存。