java运行时数据区、程序计数器(pc寄存器)、Java虚拟机栈、栈帧、局部变量表、操作数栈

深入理解JVM虚拟机 第二章 java内存区域与内存溢出异常 2.2 运行时数据区

2.2 运行时数据区

1 概述

运行时数据区
在这里插入图片描述

2.2.1 程序计数器

1.pc寄存器(程序计数器)
    可以看做(当前线程的)字节码的行号指示器(.class文件的行号,记住指令运行到哪了)
    每一个java线程都有自己的pc寄存器。
    如果该方法是nativa,那么pc寄存器得值是undefined,如果不是native的,那么pc寄存器就保存jvm正在执行的字节码指令地址。
    程序计数器是唯一一块Java虚拟机规范中没有任何规定的OutOfMemoryError情况的区域;

字节码指令集,由操作码和操作数组成,.java文件编译后的.class就是操作数和操作码的集合


2.2.2 Java虚拟机栈

    Java虚拟机栈:线程私有,这个栈和线程同时创建(生命周期与线程相同),用于存储栈帧;
    是用来描述Java方法执行的内存模型,每个方法在执行时都会创建一个栈帧

void spin(){
    
    
    int i ;
    for (i = 0;i<100;i++){
    
    
        ....
    } 
}

这个方法中,
0,100两个常量存放在操作数栈
整形变量i存放在局部变量变量表

栈帧

    用于存储局部变量表,操作数栈,动态链接,方法出口等信息,每一个方法从被调用到执行完毕,都对应者一个栈帧在虚拟机栈中入栈到出栈的过程。

1 局部变量表

    每个栈帧都包含一组变量列表,称之为局部变量表,用于存储 方法的形参和方法内部定义的变量(局部变量)(这些变量也包括引用类型),和returnAddress(返回地址类型);
这些参数和局部变量都是编译期可知的。
    注意,引用类型的局部变量也会存储在局部变量表中,只不过存储的是引用类型的地址。

    jvm使用局部变量表 完成方法调用时方法的传递
    通过索引来访问,第0个局部变量一定用来存储该实例方法所在对象的引用(this),static修饰的方法除外;

    系统不会为局部变量赋予初始值(实例变量和类变量会被赋予初始值)。也就是说局部变量表不存在类变量那样的准备阶段。

类变量,static修饰的变量

Solt

    局部变量表的容量以变量槽(Slot)为最小单位,其中64位的double和long占用2个连续的solt,访问时访问索引小的solt,
    对于byte、short以及char类型的值在局部变量表之前,会被转换为int。
    因为方法的参数和局部变量,在编译器就已经确定了,所以局部变量表的空间大小在编译器就已经确定。

2 操作数栈

    大小由编译器期决定
    标准的栈运作 ,通过出栈/压栈来访问
    操作数栈存储 常量和变量值
    jvm把局部变量表中或者对象实例中 复制常量和变量值到操作数栈中,jvm也从操作数栈中取出数据和操作数据以及把操作结果重新入栈。
    虚拟机在操作数栈中存储数据的方式和在局部变量区中是一样的,对于byte、short以及char类型的值在压入到操作数栈之前,也会被转换为int。

3 动态链接

一个引用,(当前方法所在类型的)运行时常量池的引用

好文推荐
https://blog.csdn.net/a616413086/article/details/51272309
https://zhuanlan.zhihu.com/p/45354152

猜你喜欢

转载自blog.csdn.net/qq_43369986/article/details/108949146