JVM 第二部分-1(程序计数器,虚拟机栈,本地方法栈)

第二部分:运行时数据区

请添加图片描述

1.程序计数器:

全称是程序计数寄存器,像CPU的寄存器一样,存放线程的下一条指令的地址。每个线程都有一个

(区域小,执行速度快,不会有垃圾回收,也不会报oom错)

两个问题:

  • 使用PC寄存器存储字节码指令地址有什么用呢 或者表述为 为什么使用PC寄存器记录当前线程的执行地址呢
    • 因为CPU在不停地切换线程,当切换回来时,需要通过PC寄存器知道从哪个地方开始执行
    • JVM的解释器也需要PC寄存器告诉它下一条指令在哪里
  • PC寄存器为什么被设定为线程私有
    • 因为CPU在不停地切换线程,当切换回来时,需要通过PC寄存器知道从哪个地方开始执行。要是只有一个PC寄存器,就不知道线程在中断时执行到哪个地方

2.虚拟机栈:

  • 是线程私有的,线程创建时会创建一个虚拟机栈,栈里面有栈帧,对应一个个方法。
  • 作用:管理Java方法的调用,保存方法的局部变量(不是成员变量)(8种基本类型,以及引用类型的引用),部分结果(中间结果),并参与方法的调用和返回
  • 只会进行入栈出栈操作,不会GC,但是会OOM
  • 速度快,仅次于程序计数器
  • 栈越大,可调用方法越多。栈帧越大,可,越小。局部变量表和操做数栈越大,栈帧越大

会有OOM和 StackOverflow 异常,死循环 / 内存泄露 / 方法区class对象太多 会OOM ,一直自己调用自己或者递归可能SOF

请添加图片描述

栈帧:

  • 栈顶的栈帧是当前栈帧,对应的是当前方法,当前方法所属的类是当前类
  • 执行引擎只操作当前栈帧
  • 如果当前方法调用了新的方法,会新建一个栈帧,放在栈顶,成为当前栈帧。当前方法返回,当前栈帧就会被抛弃,前一个栈帧成为当前栈帧
  • 不同的线程有不同的栈,不能引用其他栈的栈帧
  • Java方法有两种返回函数的方式:一是正常的return,void方法在字节码里有return指令,在源代码里面写不写return都行。二是有异常,但是没有处理,被抛出,也会退出程序,程序报错结束
  • 内容:
    • 局部变量表(Local Variables)(或 局部变量数组 本地变量表)
      • 定义为一个数字数组(长度为32位以内的数据占一个slot,64位占两个slot)(其他数据类型都转为int,double,long占两个slot)
      • slot是它的最基本的存储单元(变量槽)【引用变量只占一个槽】
        • slot可以回收,当局部变量过了作用域,后面的局部变量可以重复利用它之前占的槽
      • 主要用于储存方法参数和方法体里的局部变量,这些数据类型包括 基本数据类型,对象引用,returnaddress类型
      • 局部变量表是建立在线程的栈上,是线程的私有数据,所以线程安全**(所以多线程使用同一个类的同一个方法,是线程安全的)**
      • 表里面的变量只在当前方法调用中有效。方法调用完,栈帧销毁,表销毁
      • 局部变量表的大小在编译期确定下来的。并保存在方法的code属性的maximum local varibles数据项中。方法运行期间是不会改变它的大小的。
    • 操作数栈(Openrand Stack)(或称为 表达式栈)
      • 主要用于保存计算过程的中间结果,同时作为计算过程中变量临时的储存空间
      • 用数组实现
      • 操作数栈是JVM执行引擎的一个工作区。当方法开始执行时,创建新的栈帧,栈帧里创建空的操作数栈
      • 操作数栈的大小在编译期就已经确定,保存在方法的code属性中的max_stack
      • 操作数栈中的元素可以是Java数据类型的任意一个。32位的类型占用一个深度。64位占用两个
      • 操作数栈不是采用访问索引的方式进行访问。只能是通过入栈出栈进行操作
      • 如果被调用的方法有返回值,其返回值会被压入当前栈帧的操作数栈中,并更新PC寄存器指向下一条指令
      • 操作数栈中元素的数据类型必须与字节码指令的序列严格匹配,这由编译器在编译期间进行验证,同时在类加载过程中的类检验阶段的数据流分析阶段要再次验证
      • Java虚拟机的执行引擎是基于栈的执行引擎,里面的栈是操作数栈。
      • 栈顶缓存技术:因为操作数栈是在内存中的,字节码指令多,读写操作频繁,所以hotSpot jvm的设计者把栈顶元素缓存到物理的寄存器中,提高速度
    • 动态链接(Dynamic Linking)(或 指向运行时常量池的方法引用)
      • 就是一个指向运行时常量池的方法引用
      • 每个栈帧都有一个动态链接
      • 作用:
        • 使当前方法的代码支持动态链接。比如:invokedynamic指令
        • 字节码文件里有一个常量池,里面是变量和方法的引用,都是符号引用。【动态链接的作用就是把符号引用转换成调用方法的直接引用】
      • 常量池:作用就是为了提供一些符号和常量,便于指令的识别
    • 方法返回地址(Return Address)(或 方法正常退出或异常退出的定义)
      • 作用:存放调用该方法的方法的PC寄存器的值,
        • 方法正常退出:调用者的PC寄存器的值作为返回地址,即调用该方法的指令的下一条指令的地址
        • (不是很清晰)有未捕获异常退出:直接退出该方法,会给该方法的调用者产生返回值
        • 如果方法中有try catch异常,捕获异常时,根据异常表,正常捕获跳转
        • 共同点:调用结束之后,都返回调用该方法的位置
      • 返回指令:ireturn(返回值为boolean,byte,char,short,int)、lreturn、freturn、dreturn、areturn(返回引用)、return(void方法,实例初始化方法,类和接口的初始化方法)
    • 一些附加信息,例如:对重新调试提供支持的信息
    • 【有时会把 动态链接, 方法返回地址, 一些附加信息统称为 帧数据区】
    • 方法的调用:
      • 链接与绑定
        • 静态链接与动态链接
          • 都是把符号引用换成直接引用。区别是前者需要被调用方法在编译期可知,且运行时不变。后者是被调用方法在编译器无法确定下来,只能在运行时转换
        • 早期绑定和晚期绑定
          • 绑定是一个字段,方法,类在符号引用转换成直接引用的过程,这仅仅发生一次
          • 都是将方法和所属类型绑定。区别是前者是方法在编译期确定,且运行期不发生改变,后者是方法在编译期不确定
        • 面向对象的编程语言都有多态,自然具备早期绑定和晚期绑定两种方式
      • 虚方法
        • Java中的普通方法都具有虚方法的特征,相当于C++的虚函数。如果希望某个方法不具有虚函数的特征,加final修饰
          • 非虚方法:方法在编译期间就确定了具体的版本,且运行时不变
          • 静态方法,私有方法,父方法,final方法,构造方法都是非虚方法
          • 其他方法为虚方法
        • 虚拟机提供了几种方法调用指令:
          • 普通调用指令
            • invokestatic:调用static方法,编译期间确定唯一方法版本
            • invokespecial:调用方法,父类方法,私有方法,编译期间确定唯一方法版本
            • invokevirtual:调用虚方法
            • invokeinterface:调用接口方法
          • 动态调用指令:
            • invokedynamic:动态解析需要调用的方法,然后执行
              • Java7修改了虚拟机规范,在指令集加了这个指令。但是没有直接生成这个指令的方式。Java8的lambal表达式出来之后,才有了直接的生成方式
          • 前面四个指令不能干预,最后一个用户可以人为确定方法版本。 invokestatic+invokespecial+final方法(被分到invokevirtual里了)为非虚方法
      • 方法的重写
        • 方法重写的本质:
          • 1.找到操作数栈栈顶的第一个元素所执行的对象的实际类型,记作C
          • 2.如果在类型C中找到和常量中的描述和简单名称都相符的方法,则进行访问权限校验。如果校验通过则返回这个方法的直接引用,查找过程结束。校验不通过,抛出 java.lang.IllegalAccessErrorr 异常
          • 3.如果没有找到相符的方法,按继承关系从下往上对C的各个父类进行第二步的查找和校验过程
          • 4.如果始终没有找到合适的方法,则抛出 java.lang.AbstractMethodError异常
          • 【IllegalAccessErrorr 介绍:当程序试图访问或修改一个属性或调用一个方法,如果你没有权限访问,就会引起编译器异常。如果这个错误发生在运行时,就说明这个类发生了不兼容的变化】
      • 虚方法表
        • 作用:减少调用虚方法时查找目标方法的次数,用索引表代替查找【非虚方法不用查找,因为编译期就确定了】
        • 每个类都有一个,表中存放着各个方法的实际入口
        • 创建时间:虚方法表在类加载的链接阶段被创建并开始初始化,类的变量初始值准备完后,JVM会把该类的方法表也初始化完毕

面试题:

  • 举例栈溢出的情况:一直自己调用自己 或者 一直递归
  • 调整栈的大小,能保证不出现溢出吗:不能。如果一直递归不退出,只能推迟出现异常的时间
  • 垃圾回收是否会涉及到虚拟机栈:不会,栈会有OOM,但是没有GC
  • 分配的栈内存越大越好吗:不是。要合理分配,过大会导致线程数过少,而且也会影响jvm其他部分使用的空间
  • 方法中定义的局部变量是否线程安全:如果没有逃逸,只在方法内起作用,是线程安全的。但是如果逃逸了,比如传参进来,return出去,不仅仅在方法内起作用,就不是线程安全

请添加图片描述

请添加图片描述

请添加图片描述

3.本地方法栈

本地方法接口

  • 本地方法:一个Java调用非Java代码的接口,方法体是非Java方法在外面实现的
  • 使用本地方法的原因:
    • 与Java环境外交互
    • 与操作系统交互
    • Sun’s java:sun的解释器是用C实现的,这使得它能像一些普通的C一样与外部交互
  • 现在使用本地方法越来越少了,除法是和硬件相关的应用,比如通过Java程序驱动打印机或Java系统管理生产设备。因为现在的异构邻域间的通信很发达,比如用socket通信,用web service
  • native可以与除了 abstract 的所有修饰符一起用

本地方法栈

  • 也是线程私有的
  • 允许被实现成固定或动态大小(溢出和 虚拟机栈是一样的)
  • 本地方法是用C写的
  • 具体做法是在本地方法栈 登记本地方法,执行引擎执行时加载本地方法库
  • 当线程调用一个本地方法时,它就不受虚拟机限制,和虚拟机有一样的权限
    • 本地方法可以通过本地方法接口来访问虚拟机内部的运行时数据区
    • 它可以直接使用本机的寄存器
    • 直接从本地内存的堆中分配任意数量的内存
  • 不是所有虚拟机支持本地方法
  • 在hotspot jvm中,直接将本地方法栈和虚拟机栈合二为一

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/431364.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【外汇天眼】外汇投资策略:区间突破交易系统

RangeBreak系统介绍 RangeBreak区间突破交易系统被市场广泛用于日内交易,曾经连续多年在《美国期货杂志》盈利交易系统排行榜中位居前十。 目前该交易系统也仍旧被很多专业机构和个人投资者所推崇。 交易者可根据自己的交易习惯和性格特点进行改进,并不…

网络编程 24/3/4 作业

1、广播 发送端 #include <myhead.h> int main(int argc, const char *argv[]) {//创建套接字int sfdsocket(AF_INET,SOCK_DGRAM,0);if(sfd-1){perror("socket error");return -1;}//设置当前套接字允许广播属性int broadcast1;if(setsockopt(sfd,SOL_SOCKET…

numpy数据操作

numpy数据操作 读取数据 # numpy读取数据np.loadtxt(fname, 文件、字符串或产生器, 也可以是压缩文件dtypenp.float, 数据类型, 可选, 即确认csv的字符串以什么数据类型读入数组中, 默认为np.floatdelimiterNone, 分割读取的字符串, 默认是…

基于灰狼算法GWO的城市三维无人机路径规划(复杂地形三维航迹路径规划)

摘要 本文提出了一种利用灰狼算法GWO来解决城市环境下无人机三维路径规划问题的方法。这种方法将复杂的无人机航迹规划任务转化为一个优化问题&#xff0c;然后运用灰狼算法GWO来解决这个优化问题。灰狼算法GWO是一种模拟灰狼种群捕猎行为的优化算法&#xff0c;它具备强大的全…

基于springboot+vue实现校企合作项目管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现校企合作项目管理系统演示 摘要 这是一个计算机的时代&#xff0c;在计算机应用非常广泛的时代中&#xff0c;用计算机来完成对信息的处理有着非常好的使用效果。特别是针对学校而言亦是如此&#xff0c;通过在学校中的信息化建设&#xff0c;能够很好的提升…

win11环境下使用hane WIN NFS Server搭建nfs服务

如题&#xff0c;服务端使用hane win nfs server&#xff0c;客户端也是使用wins系统。 S1&#xff0c;安装nfs服务器端&#xff0c;wins系列除了server系列可以使用nfs服务端&#xff0c;其余必须使用额外的组件来实现NFS文件系统的功能。 Networking Software for Windows …

【WPS】Excel查重数据对比

数据对比 数据对比标记重复数据查询过滤处理

STL容器之map和set的补充AVL树

一、AVL树 ​ 不同搜索的对比&#xff1a;1.暴力搜索时间复杂度是O(N)&#xff1b;2.二分查找的时间复杂度是O(lgN)&#xff0c;但是伴随着有序&#xff0c;插入删除挪动数据的成本极高&#xff1b;3.二叉搜索的时间复杂度是高度次数&#xff0c;极端场景会退化为类似链表时间…

栈和队列之队列

1.队列 1.1队列的概念 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出 FIFO(First In First Out) 入队列&#xff1a;进行插入操作的一端称为队尾 出队列&#xff1a;进行删除操作的一端称为队…

android开发框架mvp,Android面试心得必备技能储备详解

面试复习路线图 我之前复习&#xff0c;大多都在20点以后&#xff0c;因为晚上比较能集中注意力&#xff0c;制定一个学习计划&#xff0c;切勿零散的复习&#xff0c;最好是系统的复习&#xff0c;才能胜却在握 主要内容如下&#xff1a; BAT的面试题目相关性能优化相关相关…

日本极致产品力|与日本所有食物百搭,年销量2亿箱的啤酒品牌

摘要&#xff1a;《极致产品力》日本深度研学,可以帮助企业找产品、找方向、找方法,在日本终端市场考察中洞悉热销产品背后的成功逻辑,了解最新最前沿的产品趋势和机会。结合日本消费趋势中国转化的众多经验,从品牌、包装、卖点、技术和生产工艺等多方面寻找中口市场的解决方案…

Echarts+D3气泡图

EchartsD3气泡图&#xff08;相邻效果&#xff0c;气泡之间不叠加&#xff09; <template><div ref"chart" style"width: 500px; height: 500px"></div> </template><script setup> import * as echarts from echarts/core …

准确率达 91.74%!东南大学提出光伏电池缺陷检测模型,首次引入神经结构搜索

乘着从全球吹来的「绿色发展、低碳转型」东风&#xff0c;光伏 (photovoltaic, PV) 产业自进入 21 世纪以来&#xff0c;便以令世人惊叹的速度迅猛向前发展。在我国&#xff0c;光伏发电更是呈现出前所未有的活力。根据 2023 年 4 月国家能源局公布的当年 1-3 月份全国电力工业…

【IO】进程间通信

A程序代码&#xff1a; #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <errno.h> #include <fcntl.h> #include <string.h> int main(int argc, const char *argv[]) {if(mkfifo…

Redis缓存【重点】

参考链接 https://xiaolincoding.com/redis/cluster/cache_problem.html#%E7%BC%93%E5%AD%98%E9%9B%AA%E5%B4%A9 目录 缓存雪崩大量数据同时过期Redis 故障宕机 缓存击穿第一种方案&#xff0c;非法请求的限制第二种方案&#xff0c;缓存空值或者默认值第三种方案&#xff0c;使…

Docker中使用nginx-rtmp推拉网络摄像头视频流

前言&#xff1a; 该部分比较麻烦&#xff0c;闹腾了好久&#xff08;ffmpeg推拉流没学过&#xff0c;事实证明依葫芦画瓢是不行滴&#xff0c;后面有时间再学吧&#xff09;&#xff0c;后来借助chatGPT勉强解决&#xff0c;但不是很懂。因个人能力有限&#xff0c;只复述操作…

合泰HT66F2390----定时器中断学习笔记

前言 无需多言 直接开始定时器中断 的学习 通过上次的PWM学习&#xff0c;上次用的是周期型TM定时器模块 这次使用标准型TM定时器模块&#xff08;STM&#xff09; 代码 #include <HT66F2390.h>void Timer0_Init(void){_stm0c0 0b00001000;_stm0c1 0b11000001;_stm…

Vmware虚拟机安装openEuler 20.03 LTS(openEuler20.03)

文章目录 vmware虚拟机安装openEuler 20.03 LTS安装硬件设备&#xff08;略&#xff09;安装OS镜像下载镜像版本发布说明开始安装&#xff08;vmware虚拟机&#xff09;安装操作系统必要操作关闭防火墙设置selinux为宽容模式系统内核问题禁用系统内核更新 ~~禁用yum update和dn…

Ubuntu18.04运行ORB-SLAM3

ORB-SLAM3复现(ubuntu18) 文章目录 ORB-SLAM3复现(ubuntu18)1 坐标系与外参Intrinsic parameters2 内参Intrinsic parameters2.1 相机内参① 针孔模型Pinhole② KannalaBrandt8模型③ Rectified相机 2.2 IMU内参 3 VI标定—外参3.1 Visual calibration3.2 Inertial calibration…

构造pop链

反序列化视频笔记 第一步&#xff1a;找到目标触发echo调用$flag 第二步&#xff1a;触发_invoke函数调用appeng函数$varflag.php&#xff08;把对象当成函数&#xff09; 第三步&#xff1a;给$p赋值为对象&#xff0c;即function成为对象Modifier却被当成函数调用&#xff…