IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> JAVA虚拟机栈 -> 正文阅读

[Java知识库]JAVA虚拟机栈

栈是运行时的单位,堆是存储的单位。

在这里插入图片描述

JAVA虚拟机栈的概念
每个线程在创建时都会创建一个虚拟机栈,其内部保存一个个栈帧,对应着一次次的方法调用,是线程私有的(生命周
期和线程一致)。主管JAVA程序的运行
虚拟机栈的特点
1.访问速度快,仅次于程序计数器。
2.JVM直接对栈的操作有两个,及入栈(方法调用)和出栈(方法执行完毕)。
3.对于栈来说不存在垃圾回收。
栈可能出现的异常
1.固定大小的栈(通过-Xss设定)如果线程请求分配的栈空间大于设定的值,会抛出StackOverflowError。
2.动态扩展的栈,在尝试扩展时无法申请到足够的内存,或者在创建新线程时没有足够的内存去创建对应的虚拟机栈,则会报OutOfMemoryError。
栈的存储单位:栈帧
每个线程都有自己的栈,在这个线程上执行的每个方法都各自对应一个栈帧。而且执行引擎运行的所有字节码指令只针对栈顶的那个栈帧进行操作。如果当前方法调用了别的方法,对应的新的栈帧会被创建,并且放到栈顶。栈为线程私有,所以两个线程之间的栈帧无法互相引用
栈帧当中包含:
1.局部变量表(本地变量表)
.局部变量表定义为一个数组,大小在编译时期确定,主要用于存储方法参数和定义在方法体内的局部变量(基本数据类型,对象引用)。
在这里插入图片描述
如图,序号0代表this(非静态方法通过对象调用,所以有一个this代表当前对象),序号1为方法参数a,序号2位局部变量b,所以这个方法的局部变量表槽数为3。
局部变量表的最基本存储单元为槽(Slot)32位的,long和double占两个槽(访问时访问第一个槽的索引),其余占一个槽(byte、short、char、boolean都会被转换为int),JVM会为局部变量表中的每一个Slot都分配一个访问索引,通过这个索引即可访问到表中局部变量的值。
在这里插入图片描述
在栈帧中,与性能调优关系最为密切的部分就是局部变量表,在方法执行时,虚拟机使用局部变量表完成方法的传递。
局部变量表中的变量也是垃圾回收的重要根节点,只要被局部变量表中直接引用或间接引用的对象都不会被回收。
2.操作数栈(操作“数”的栈)
操作数栈主要用于保存计算过程的中间结果,同时作为计算中变量的临时存储空间。最大深度也在编译期确定,和局部变量表一样long和double也占两个栈单位深度。操作数栈不能通过索引访问,只能入栈和出栈来完成数据防问。
如果被调用的方法有返回值,他的返回值会被压入当前栈帧的操作数栈中,并更新PC寄存器中下一条需要执行的字节码指令。

在这里插入图片描述
栈顶缓存:将栈顶元素全部缓存到物理cpu的寄存器中,降低堆内存的读写次数,提升执行引擎的效率。
3.动态链接
在运行时,每个栈帧(方法)中都保存着指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了方法调用过程中的动态链接。在运行时符号引用转换为直接引用(非静态方法,只有在运行时才能确定真正执行的方法,比如只有运行时才能知道真正是哪个子类的方法该被执行),这种转换称之为动态链接。
静态链接:在类加载的链接的解析阶段,对于静态方法会直接由符号引用转换为直接引用。
在这里插入图片描述

方法的调用
静态链接和动态链接
在这里插入图片描述
早期绑定和晚期绑定
在这里插入图片描述
比如一个方法的参数传入了一个父类,这个就是晚期绑定,因为不运行这个方法就不知道传入的是子类还是父类(多态)。非静态方法也是这种,只有在运行时才确定调用它的是父类还是子类。
非虚方法和虚方法
在这里插入图片描述
虚拟机提供的方法调用指令
在这里插入图片描述

    public void show() {
        //invokestatic静态方法
        showStatic("atguigu.com");
        //invokestatic父类静态方法
        super.showStatic("good!");
        //invokespecial私有方法
        showPrivate("hello!");
        //invokespecial父类普通方法 这个也为非虚方法!!因为编译期就确定
        super.showCommon();
        //invokevirtual
        showFinal();//因为此方法声明有final,不能被子类重写,所以也认为此方法是非虚方法。
        //虚方法如下:
        //invokevirtual 父类的方法,没有用super 所以也可能是子类重写过,所以为虚
        showCommon();
        //子类的普通方法为虚方法
        info();
        MethodInterface in = null;
        //invokeinterface //接口的方法为也为虚方法
        in.methodA();
    }

虚方法表
在面向对象的编程中,会频繁的用到动态分配,为了提高性能,每个类都有一个虚方法表(在类的方法去中),存放各个方法的实际入口。虚方法表会在类加载的链接阶段被创建并初始化,类的变量初始值准备完成之后,JVM会把该类的虚方法表也初始化完毕。(不用每次调用一个方法都去寻找,本类,父类,父类的父类这样)
在这里插入图片描述
dog类自定义了sayhello,重写了tostring 所以这两个存到自己的虚方法表。
在这里插入图片描述

CockerSpaniel继承dog类,实现了Friendly接口,重写了sayHello和sayGoodbye方法,所以这两个方法存到自己的虚方法表,而tostring存到dog的虚方法表中。
在这里插入图片描述
cat类实现了Friendly接口,重写了sayHello和sayGoodbye方法,重写了object类的finalize方法和tostring方法,自定义了eat方法,所有这5个方法都存到自己的虚函数表中。
动态类型语言和静态类型语言
在这里插入图片描述
java是静态类型语言,比如 定义 int a =10;是在编译器就要检查a的类型的。int a = “1”;编译要报错
4.方法返回地址
存放调用该方法的PC寄存器的值
意思就是方法A调用方法B,方法B中存放一条方法A的PC寄存器的值,等待方法B执行完毕之后,B中的方法返回地址可以保证方法A继续准确执行。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

5.一些附加信息

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-12-08 13:41:02  更:2021-12-08 13:42:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:26:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码