JVM学习 运行时数据区 PC寄存器、本地方法栈、虚拟机栈

2、运行时数据区

哔哩哔哩 尚硅谷视频 宋红康老师

JVM学习 运行时数据区 PC寄存器、本地方法栈、虚拟机栈

2.1、程序计数器(PC寄存器)

作用

PC寄存器用来存储指向下一条指令的地址,也就是即将要执行指令的代码。由执行引擎读取下一条指令

注意:每个线程独一份PC寄存器

测试

package com.mhy.day02;

public class PCTest01 {
    public static void main(String[] args) {
        int i = 10;
        int j = 20;
        int k = i + j;

        System.out.println(k);
    }
}

使用 javap -v PCTest01.class 进行反编译后

 Code:
      stack=2, locals=4, args_size=1
         0: bipush        10
         2: istore_1
         3: bipush        20
         5: istore_2
         6: iload_1
         7: iload_2
         8: iadd
         9: istore_3
        10: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        13: iload_3
        14: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        17: return

JVM学习 运行时数据区 PC寄存器、本地方法栈、虚拟机栈

2.2、虚拟机栈

基本内容

  • Java虚拟机栈,早期也叫Java栈,每个线程在创建时都会创建一个虚拟机栈,其内存保存一个一个的栈帧,对应一次一次Java方法的调用 注意:每个栈是线程私有的
  • 生命周期和线程一致
  • 作用:主管Java程序的运行,它保存方法的局部变量、部分结果,并参与方法的调用与返回

栈帧的内部结构

  • 局部变量表(Local Variables)
  • 操作数栈(Operand Stack)(或表达式栈)
  • 动态链接(Dynamic Linking)(或指向运行时常量池的方法引用)
  • 方法返回地址(Return Address)(或方法正常退出或者异常退出的定义)
  • 一些附加信息

JVM学习 运行时数据区 PC寄存器、本地方法栈、虚拟机栈

1.局部变量表(Local Variables)

  • 局部变量表也被称之为局部变量数组或本地变量表
  • 定义为一个数字数组,主要用于存储方法参数和定义在方法体内的局部变量,这些数据类型包括各类基本数据类型、对象引用(reference),以及returnAddress类型
  • 由于局部变量表也是建立在线程的栈上,是线程的私有数据,因此不存在数据安全问题
  • 局部变量表所需的容量大小是在编译期确定下来的,并保存在方法的Code属性的maxmum local variables数据项中。在方法运行期间是不会改变局部变量表的大小的
  • 方法嵌套调用的次数由栈的大小决定
  • 局部变量表中的变量只在当前方法调用中有效

测试:

package com.mhy.test1;

import java.util.Date;

public class LocalVariablesTest {
    private int count = 0;

    public static void main(String[] args) {
        LocalVariablesTest localVariablesTest = new LocalVariablesTest();
        int num = 1;
        localVariablesTest.fun1();
        System.out.println(localVariablesTest.count);
    }

    public void fun1() {
        Date date = new Date();
        String str = "Hello JVM";
        double dd = 0.22;
        String s = fun2(str, date);
        System.out.println(s);
    }

    public String fun2(String string,Date date){
        System.out.println(date);
        System.out.println(string);
        System.out.println(fun3());
        return "fun2";
    }

    public int fun3(){
        int a = 1;
        {
            int b = 2;
            b = a + b;
        }
        int c = a + 1;
        return c;
    }
}

根据编译的class用 jclasslib is a bytecode viewer 来查看结果

JVM学习 运行时数据区 PC寄存器、本地方法栈、虚拟机栈

先查看main 是static类型的

public static void main(String[] args) {
    LocalVariablesTest localVariablesTest = new LocalVariablesTest();
    int num = 1;
    localVariablesTest.fun1();
    System.out.println(localVariablesTest.count);
}

JVM学习 运行时数据区 PC寄存器、本地方法栈、虚拟机栈

JVM学习 运行时数据区 PC寄存器、本地方法栈、虚拟机栈

注意:这里局部变量最大槽数是指局部变量占的大小,一般的int、char、引用类型等等占1个槽,long、double等等占2个槽

JVM学习 运行时数据区 PC寄存器、本地方法栈、虚拟机栈

JVM学习 运行时数据区 PC寄存器、本地方法栈、虚拟机栈

查看非static类型的方法

public String fun2(String string,Date date){
    System.out.println(date);
    System.out.println(string);
    System.out.println(fun3());
    return "fun2";
}

JVM学习 运行时数据区 PC寄存器、本地方法栈、虚拟机栈

带有作用域的局部变量

public int fun3(){
    int a = 1;
    {
        int b = 2;
        b = a + b;
    }
    int c = a + 1;
    return c;
}

JVM学习 运行时数据区 PC寄存器、本地方法栈、虚拟机栈

变量的分类

  1. 按照数据类型分类:
  2. 基本数据类型
  3. 引用数据类型
  4. 按照类中声明的位置分类:
  5. 成员变量:在使用之前都经历过默认初始化阶段
    • 类变量:linking 的 prepare 阶段赋默认值 —–> initial 阶段初始化
    • 实例变量:随着对象的创建会在堆空间中分配实例变量空间,并进行默认赋值
  6. 局部变量:在使用前必须赋值,否则编译不通过

2.操作数栈(Operand Stack)

操作数栈,在方法执行过程中,根据字节码指令,往栈中写入数据或提取数据,即入栈(push)和出栈(pop)

测试

package com.mhy.test1;

public class OperandStackTest {
    public static void main(String[] args) {
        new OperandStackTest().test();
    }
    public void test(){
        byte a = 11;
        int b = 12;
        int c = a + b;
    }
}

指令

 0 bipush 11
 2 istore_1
 3 bipush 12
 5 istore_2
 6 iload_1
 7 iload_2
 8 iadd
 9 istore_3
10 return

代码跟踪

JVM学习 运行时数据区 PC寄存器、本地方法栈、虚拟机栈

这里可以看出局部变量的长度为4还一个0位置为this,操作数栈的深度为2

3.动态链接(Dynamic Linking)

每一个栈帧内部都包含一个指向运行时常量池中该栈帧所属方法的引用,包含这个引用的目的就是为了支持当前方法代码能够实现动态链接
动态链接的作用就是为了将这些符号引用转换为调用方法的直接引用

JVM学习 运行时数据区 PC寄存器、本地方法栈、虚拟机栈

4.方法的调用

虚方法与非虚方法

  • 非虚方法
  • 该方法在编译器就确定了具体的调用版本,这个版本在运行时是不可变的,这样的方法称为非虚方法
  • 静态方法、私有方法、final修饰的方法、实例构造器、父类方法都是非虚方法
  • 除了上面以外的方法都是虚方法

虚方法与非虚方法的指令

  • 普通指令
invokestatic : 调用静态方法,解析阶段确定唯一方法版本
invokepecial : 调用方法、私有及父类方法,解析阶段确定唯一方法版本
invokevirtual : 调用所有虚方法
invokeinterface : 调用所有接口方法
  • 动态指令
invokedynamic : 动态解析需要调用的方法,然后执行

方法重写的本质

  1. 找到操作数栈顶的第一个元素所执行的对象的实际类型,记为 C
  2. 如果在过程结束后:如果不通类型 C 中找到与常量中的描述符合简单名称都相符的方法,则进行访问权限校验,如果通过就返回这个方法的直接引用,查找过,则返回 java.lang.IllegalAccessError 异常
  3. 否则,按照继承关系依次从下倒上对 C 的各个父类进行第二步的搜索与校验
  4. 如果始终没有找到合适的方法,则抛出 java.lang.AbstractMethodError 异常

java.lang.IllegalAccessError 异常

程序试图访问或修改一个属性或者方法,这个属性或者方法你没有权限,就会引起编译时异常,一般在运行时发生

5.方法返回地址(Return Address)

  • 存放调用该方法的PC寄存器的值
  • 一个方法的结束有两种方式
  • 正常执行完成
  • 出现未处理的异常,非正常退出
  • 正常退出:调用者的PC计数器的值作为返回地址,即调用该方法的指令的下一条指令的地址;异常退出,有异常表来决定返回地址

2.3、本地方法接口

JVM学习 运行时数据区 PC寄存器、本地方法栈、虚拟机栈

什么是本地方法?

一个 Native Method 就是一个Java调用非java代码的接口。一个 Native Method 就是这样一个方法,该方法非java语言实现,比如说C。

为什么要使用Native Method?

  • 与Java环境外交互:有时Java应用需要与Java外面的环境交互,这是本地方法存在的主要原因
  • 与操作系统交互:通过使用本地方法,我们得以用Java实现了jre的与底层系统的交互,甚至JVM的一部分代码都是使用C写的
  • Sun Java:Sun的解释器就是用C写的,它使得它能像一些普通的C一样与外部交互

2.4、本地方法栈

Java虚拟机用以管理Java方法的调用,而本地方法栈用于管理本地方法的调用-

  • 当某个线程调用一个本地方法时,它就进入了一个全新的并且不再受虚拟机限制的世界。它和虚拟机拥有同样的权限
  • 本地方法可以通过本地方法接口来访问虚拟机内部的运行时数据区
  • 它甚至可以直接使用本地处理器中的寄存器
  • 直接从本地内存的堆中分配任意数量的内存
  • 本不是所有的JVM都支持本地方法,因为Java虚拟机规范并没有明确要求本地方法栈的使用语言、具体实现方法、数据结构等。
  • 在 Hotspot JVM 中,直接将本地方法栈和虚拟机栈合二为一

Original: https://www.cnblogs.com/shuisanya/p/16693651.html
Author: 水三丫
Title: JVM学习 运行时数据区 PC寄存器、本地方法栈、虚拟机栈

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/581430/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 模板层

    过滤器 语法结构 {{ 数据对象|过滤器名称:参数 }} 过滤器最多只能额外传输一个参数 常见过滤器 标签 注意事项 在django模板语法中写标签的时候,只需要写关键字然后tab…

    Linux 2023年6月7日
    082
  • MongoDB安装使用教程

    MongoDB安装使用教程 介绍 MongoDB是一个基于分布式文件存储的数据库,是一个文档数据库,支持的数据结构非常松散,是类似json的bson格式,可以存储比较复杂的数据类型…

    Linux 2023年6月6日
    087
  • 继上篇-jquery ajax提交 本篇用ajax提交的数据去数据库查询

    上篇讲到如何用jquery ajax提交数据至后台,后台接收并返回给ajax。https://www.cnblogs.com/tiezhuxiong/p/11943328.html…

    Linux 2023年6月13日
    093
  • Linux网络智障问题排查汇总

    Q: Linux 客户端应用接收不到组播:A: 检查客户端的 Linux 系统,可能没有配置 net.ipv4.conf.ethx.rp_filter = 0 的内核参数 Q: 在…

    Linux 2023年6月14日
    071
  • Redis下载及安装(windows版)

    Redis下载及安装(windows版) 下载地址1、Github下载地址:https://github.com/MicrosoftArchive/redis/releases2、…

    Linux 2023年5月28日
    078
  • CentOS/Redflag 7.3安装qemu 5.0记录

    安装实际上相当简单,只需下载源代码并编译即可。 [En] Installation is actually quite simple, just download the sour…

    Linux 2023年5月27日
    099
  • 设计模式——面向对象设计原则

    面向对象设计原则 都是为了高内聚低耦合原则。编程时基本都要遵守 分类原则:一种人只干一种事。 举例:(比较简单就不代码了) 人可以干的事情有很多:敲代码、唱歌、跳舞、打篮球&#82…

    Linux 2023年6月7日
    0143
  • 输入输出函数

    IDLE name=input(‘输入’) print(name) print函数 print(1,2) print(1,2,sep=",") input函数 …

    Linux 2023年6月8日
    072
  • ShardingSphere-proxy-5.0.0建立mysql读写分离的连接(六)

    一、修改配置文件config-sharding.yaml,并重启服务 # Licensed to the Apache Software Foundation (ASF) unde…

    Linux 2023年6月14日
    0103
  • JAVA设计模式-原型模式

    JAVA设计模式-原型模式 介绍 原型模式是一种创建型模式,用于创建重复的对象,并且保证性能。原型模式创建的对象是由原型对象自身创建的,是原型对象的一个克隆,和原型对象具有相同的结…

    Linux 2023年6月6日
    085
  • Linux上安装tomcat

    参考https://www.digitalocean.com/community/tutorials/how-to-install-apache-tomcat-8-on-cento…

    Linux 2023年6月6日
    084
  • 每周一个linux命令(ping)

    基础环境 ping命令介绍 ping命令主要用来…

    Linux 2023年6月8日
    081
  • OrchardCore Headless建站

    说到CMS系统,可能大家都能想起 WordPress和 Drupal之类的框架,作为.NET爱好者,一般也是知道一些基于.NET的CMS框架的,典型的比如 DNN、 Umbraco…

    Linux 2023年6月6日
    093
  • Python递归遍历目录下所有文件

    递归遍历目录下所有文件 方法一 import os def gci(filepath): #遍历filepath下所有文件,包括子目录 files = os.listdir(fil…

    Linux 2023年6月13日
    0100
  • 读书笔记:CSAPP 11章 网络编程

    深入理解计算机系统 第11章 本章代码:Index of /afs/cs/academic/class/15213-f15/www/code/22-netprog2其中包含本章课本…

    Linux 2023年6月13日
    093
  • 正则表达式

    基本正则表达式 元字符 . 匹配任意单个字符 [root@localhost ~]# mkdir /temp [root@localhost temp]# touch {1..9}…

    Linux 2023年6月13日
    087
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球