JVM虚拟机栈

2023-05-16

虚拟机栈

每个线程在创建时都会创建一个虚拟机栈,其内部保存一个个栈帧,对应一次次java方法的调用(线程私有
生命周期与线程一致。
作用:主管java线程的运行,保存局部变量(8种基本数据变量,对象引用地址)、部分结果,并参与方法的调用和返回。

对于栈来说不存在垃圾回收。

栈的存储单位(栈帧)

栈帧与方法一对一,进栈调用,出栈结束。
在这里插入图片描述
java两种返回函数的方式:return指令正常返回、抛异常。两种方式都会导致栈帧被弹出

栈帧中存储着:

  • 局部变量表(Local Variable)
  • 操作数栈(Operand Stack)(或表达式栈)
  • 动态链接(Dynamic Linking)(或指向运行时常量池的方法引用)
  • 方法返回地址(或方法正常退出、异常退出的定义)
  • 一些附加信息
    在这里插入图片描述

局部变量表(Local Variables)

  1. 定义数字数组,主要存储方法参数和定义在方法体内的局部标量,这些数据类型有 基本数据类型、对象引用(reference)、returnAddress类型。
  2. 由于局部变量建立在线程的栈上,是线程的私有数据,不存在数据安全问题
  3. 局部变量所需的大小是在编译期确定下来的,并保存在方法的code属性maximun local variables。在方法运行期间不会改变局部变量表的大小。

局部变量表是栈帧中最大的部分,与性能调优关系密切。
局部变量表中的变量是重要的垃圾回收根节点,只要被局部变量表中直接或间接应用都不会被回收。

solt(变量槽)

solt 局部变量表的基本储存单位,32位以内的类型只占用一个solt(包括 returnAddress),64位类型(long,double)占用两个solt。

如果当前帧是由构造方法或者实列方法创建的(非静态),那么该对象引用的this将会存放在index为0的slot处。

solt重复利用:栈帧中的局部变量中的槽位是可以重复利用,如果一个局部变量过了其它作用域,那么在其作用域之后新的局部变量就很有可能会利用重复过期局部标量的槽位,从而达到节省资源的目的。

操作数栈

用数组或链表实现,编译时长度确定。
操作数栈在方法执行中,根据字节码指令,往栈中写入数据或读出数据。
java虚拟机的解释引擎是基于操作数栈的执行引擎。
操作数栈主要用于保存计算过程的中间结果,同时作为计算过程中变量的临时存储空间。
操作数栈数据访问是通过入栈出栈,而并非访问索引的方式。
如果被调用的方法具有返回值,其返回值将会被压入当前栈帧的操作数栈中。

栈顶缓存

将栈顶元素全部缓存在物理cpu的寄存器中,以此降低对内存的读写次数,提高执行引擎的效率。

动态链接(指向运行时常量池的方法引用)

在字节码文件中,所有的变量和方法引用都作为符号引用(#6)保存在class文件的常量池里。一个方法调用另一个方法时就是通过常量池中指向方法的符号来表示。动态链接的作用就是为了将这些符号引用转换为调用方法的直接引用。
在这里插入图片描述

方法的调用

在JVM中,将符号引用转换为调用方法的直接引用与方法得绑定机制有关。

  • 静态链接:
    当字节码进入JVM内部时,如果被调用的目标方法在编译器可知,且运行期保持不变。这种情况将调用方法得符号引用转换为直接引用称之为静态链接。
  • 动态链接:
    如果被调用的方法在编译期无法确定下来,就是说只能在程序运行期将调用方法的符号引用转换为直接引用。具有动态性,称之为动态链接。
  • 非虚方法:
    如果方法在编译期就确定了具体的调用版本,这个版本在运行时是不可变的,称之为虚方法。(静态方法、私有方法、final方法,实例构造器,父类方法)。不涉及多态的形式
  • 虚方法:
    在编译期无法确定此方法是哪一个具体类的方法,在程序运行期根据实际类型才能确定

虚拟机调用指令:

  1. invokestatic:调用静态方法
  2. invokespecial:调用 < init>()方法,私有父类方法,
  3. invokevirtual:调用虚方法
  4. invokeinterface:调用接口
  5. invokedynamic:动态解析需要调用的方法,然后执行(lambda表达式)

(1)(2)调用的是非虚方法。
(3)(4)除final修饰的方法,调用的是虚方法

方法返回地址(return Address)

存放调用方法的PC寄存器的值。
方法调用无论以哪种方式退出,在方法退出后都会返回到该方法被调用的位置。方法正常退出时,调用者的PC计数器的值作为返回地址,即该方法的下一条指令的地址。异常退出的:返回地址要通过异常表来确定,栈帧中一般不保存这部分信息。

正常完成出口与异常完成出口(例没有用try,catch处理异常)的区别是:异常完成出口不会给上层调用者产生任何返回值,异常信息存储在异常处理表中。

栈的相关面试题

  1. 举例栈溢出的情况(StackOverflowError):
    栈帧中最大存储部分是局部表量表,当局部变量表过大是容易造成栈溢出,举例main无限递归调用自己。解决:通过 -Xss 设置栈的大小、OOM

  2. 调整栈的大小,就能保证栈不出现溢出吗?
    不能保证,比如无限递归只能保证栈溢出晚一点

  3. 分配的栈内存越大越好吗?:
    不,内存有限,栈内存大了,其它线程分得就少了

  4. 垃圾回收是否会涉及到虚拟机栈?:不会!!!

  5. 方法中定义的局部变量是否会线程安全?:
    只有一个线程操作此数据,则线程安全。
    如果有多个线程操作此数据,则此数据是共享数据,若不考虑同步机制的话,则存在线程安全问题。
    在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JVM虚拟机栈 的相关文章

  • 估计 64 位 Java 中最大安全 JVM 堆大小

    在分析存在一些问题的 64 位 Java 应用程序的过程中 我注意到分析器本身 YourKit 正在使用真正大量的内存 我在 YourKit 启动脚本中得到的是 JAVA HEAP LIMIT Xmx3072m XX PermSize 25
  • Java 堆被无法访问的对象淹没

    我们的 Java EE 应用程序开始出现一些严重问题 具体来说 应用程序在启动后几分钟内就运行了高达 99 的老年代堆 不会抛出 OOM 但实际上 JVM 没有响应 jstat 显示老年代的大小根本没有减少 没有垃圾收集正在进行 并且kil
  • 最近有关于 JVM 的书吗? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • STS 无法在我的计算机上启动

    我试图在 eclipse 上设置 Spring mvc 项目 基本项目进展顺利 但是使用 Restful 服务 Jersey 等开始出现许多与依赖项相关的错误 所以我打算转到STS 我正在使用 STS 2 9 2 它给我 无法创建java虚
  • java.library.path 中没有字体管理器

    以下代码在我的桌面上运行得很好 BufferedImage image new BufferedImage width height BufferedImage TYPE INT RGB Graphics g image getGraphi
  • 在intellij中为java启用ssl调试

    从我的问题开始 上一期尝试通过 tls ssl 发送 java 邮件 https stackoverflow com questions 39259578 javamail gmail issue ready to start tls th
  • 一个好的 Java VM 中方法调用的开销是多少?

    有人可以提供反汇编的机器代码汇编程序列表吗 我的意思是 与 C 中的普通函数调用相比 肯定有一些开销 VM 需要跟踪调用以查找热点 并且当它使用编译代码时 如果新加载的类需要重新编译 它需要提供动态更改编译方法的方法 我想某处也有返回堆栈溢
  • Scala 中的多个类型下限

    我注意到tuple productIterator总是返回一个Iterator Any 想知道是否无法设置多个下限 因此它可能是最低公共超类型的迭代器 我尝试并搜索了一下 但只发现this https stackoverflow com q
  • Scala 对大数的阶乘有时会崩溃,有时不会

    以下程序经过编译和测试 有时返回结果 有时充满屏幕 java lang StackOverflowError at scala BigInt apply BigInt scala 47 at scala BigInt equals BigI
  • Java GuardedString - 用于加密的随机密钥是否存储在 Java 堆内存中?如果不是,那么密钥保存在哪里?

    Oracle 的 org identityconnectors common security GuardedString 要转换为 GuardedString 的原始数据需要由 EncryptorImpl class 随机生成的加密密钥
  • 当目标是属性时,@Throws 不起作用

    在看的同时这个问题 https stackoverflow com q 47737288 7366707 我注意到申请 Throws to a get or setuse site 没有影响 此外 唯一有效的目标 for Throws ar
  • JVM内存段分配

    好吧 我有一个关于 JVM 内存段的问题 我知道每个 JVM 都会选择稍微不同地实现这一点 但这是一个总体概念 在所有 JVM 中应该保持相同 一个在运行时不使用虚拟机执行的标准C C 程序在运行时有四个内存段 代码 堆栈 堆 数据 所有这
  • Java 类:匿名类、嵌套类、私有类

    有人能解释一下Java中匿名类 嵌套类和私有类之间的区别吗 我想知道与每个相关的运行时成本以及每个编译器的方法 这样我就可以掌握哪个最适合用于例如性能 编译器优化的潜力 内存使用以及其他 Java 编码人员的普遍可接受性 我所说的匿名类是指
  • 在进行堆转储后,如何在发生 OutOfMemoryError 时重新启动 JVM?

    我知道关于 XX HeapDumpOnOutOfMemoryError https stackoverflow com q 542979 260805JVM 参数 我也知道 XX OnOutOfMemoryError cmd args cm
  • 为什么同样的算法在 Scala 中运行比在 C# 中慢得多?以及如何让它更快?

    该算法根据序列中每个成员的变体创建序列的所有可能变体 C 代码 static void Main string args var arg new List
  • 线程上下文类加载器和普通类加载器的区别

    线程的上下文类加载器和普通类加载器有什么区别 也就是说 如果Thread currentThread getContextClassLoader and getClass getClassLoader 返回不同的类加载器对象 将使用哪一个
  • 使用 libjvm.so 时出现 Sigsegv Java 致命错误

    我正在做重启测试Sles12sp2 using STAF v3 4 24一段时间后我收到此错误 A fatal error has been detected by the Java Runtime Environment SIGSEGV
  • ASM之前看一下maxStack指令吗?

    我正在尝试使用 ASM 库将字节代码转换为不同的格式 这可以使用 MethodVisitor 来完成 就像这个简单的测试代码一样 return new MethodVisitor ASM7 Override public void visi
  • 是否可以强制 JVM 在堆中而不是堆中创建对象?

    我读过一些文章 有时JVM会识别一些对象并尝试在堆栈中而不是堆中创建它 因为堆栈上的内存分配比堆中的内存分配便宜 堆栈上的释放是免费的 并且堆栈由以下方式有效管理 运行时 那么 堆栈中的对象分配是如何工作的 有什么方法可以强制 JVM 执行
  • java内存不足然后退出

    我有一个必须分析大文件的软件 限制输入或提供无限内存都不是一个选择 所以我必须忍受飞行的 OOME 因为 OOME 只杀死线程 所以我的软件运行在一些糟糕的状态 从外面看一切都很好 因为进程正在运行 但在内部却是脑死亡 我想拔掉它的插头 但

随机推荐

  • win7+linux双系统下删除linux系统

    装了Windows和linux双系统的朋友 xff0c 在后期要删除linux是个比较头痛的问题 xff0c 因为MBR已经被linux接管 xff0c 本文的目的是如何在windows 和linux双系统下 xff0c 简单 xff0c
  • 迭代器详解

    迭代器 前言一 可迭代对象 xff08 Iterable xff09 xff08 一 xff09 遍历对比 xff08 二 xff09 可迭代对象 xff08 Iterable xff09 1 确定可迭代对象2 确定共同属性3 错误 二 迭
  • GD32F130移植FreeRTOS

    最近淘到一块板子 xff0c 板载GD32F130C8T6 Cortex M3内核 xff0c 64KBFalsh 8KBSRAM 最近正在看FreeRTOS 就拿它来练练手 一 下载GD库文件 习惯了用STM32 xff0c 对GD3 1
  • Cy7c68013A速度测试教程

    手里有一个cypress的CY7C68013A模块 xff0c 一直没空玩 今天便测一下 xff0c 这个模块的USB2 0速率 1 开发工具下载 在cypress下载如下开发工具包 xff08 开发工具包下载地址 xff09 2 工具包安
  • Linux kernel编译

    bin bash echo 34 Configure the kernel 34 until echo 34 1 make the am335x lierda defconfig 34 echo 34 2 make the menuconf
  • Openwrt二级路由获取IPV6

    由于没有公网IPV4 便研究了一下公网IPV6 网上大部分是将光猫改为桥接 xff0c 然后路由拨号 xff0c 获取公网IPV6地址 xff0c 但目前不想这样做 研究一下 xff0c 二级路由下的IPV6获取 按照网上的说明 xff0c
  • 从RK3399的安卓系统中提取dts

    不久前淘到一块RK3399的板子 xff0c 安卓7 1的系统 xff0c 可是翻遍全网没有任何资料 便想着从系统中提取设备树文件 xff0c 自行适配linux系统 1 系统备份 参考该RK3328系统备份文章 xff0c 安装好驱动 x
  • MATALB 卷积神经网络 图片二分类

    正忙着写论文的时候 xff0c 突然看到她的询问 xff0c 连续两晚失眠 xff0c 有了这个程序 以前没用过神经网络 xff0c 所有代码都是基于别人基础上修改 xff0c 仅限于能实现自己需要的功能 从GitHub找到一个创建用于图像
  • MATLAB调用训练好的卷积神经网络

    上一篇链接 xff1a MATALB 卷积神经网络 图片二分类 上一篇已经介绍了如何对数据通过CNN进行深度学习分类 xff0c 并将训练好的模型保存下来 这里将介绍一下如何调用自己已经训练好的模型进行数据分类 1 加载模型 clear c
  • Unity URP DOTS Pathfinding+Local avoidance

    Unity URP DOTS Pathfinding 43 Local avoidance RVO2的效果还是蛮好的
  • 使用Python+Scrapy爬取并保存QQ群空间帖子

    首先声明 xff0c 在Python和爬虫这方面 xff0c 我是业余的那一卦 xff0c 只是平时玩一玩 xff0c 不能当真的 xff0c 请各位大佬轻拍 虽然爬虫与传统意义上的大数据技术不属于同一类 xff0c 但大概也只能放在大数据
  • SLAM 多点导航功能包发布

    SLAM 多点导航功能包 navi multi goals pub rviz plugin 描述 xff1a 该功能包为SLAM 建图导航提供可发布多个目标点任务的导航方式 要求 必须基于 Autolabor SLAM导航使用 一 安装与配
  • 步进电机学习笔记

    扩充的理论知识 xff1a 步进电机的细分技术实质上一种电子阻尼技术 xff0c 其主要目的是减弱或消除低频振动 不同厂家的细分驱动器精度可能差别很大 xff0c 还取决于细分电流控制精度等因素 细分数越大 xff0c 精度越难控制 xff
  • 错误:AttributeError: module ‘cv2.cv2‘ has no attribute ‘TrackerCSRT_create‘ 解决

    OpenCV目标跟踪运行出错 xff1a AttributeError module cv2 cv2 has no attribute 39 TrackerCSRT create C 问题 xff1a 直接上错误代码 xff1a 上我的代码
  • STM32系列(HAL库) ——使用串口打印的3种方式

    一 前期准备 1 硬件 xff1a STM32C8T6最小系统板USB TTL串口模块ST Link下载器 2 软件 xff1a keil5 IDEcubeMX 二 cubeMX配置 1 配置RCC 选择外部时钟源 2 配置SYS Seri
  • C#多线程编程:线程基础

    原文链接 xff1a https www cnblogs com wyt007 p 9486752 html 创建线程 static void Main string args Thread t 61 new Thread PrintNum
  • ROS 控制Innfos机械臂简单例子

    include lt ros ros h gt include lt image transport image transport h gt include lt sensor msgs image encodings h gt incl
  • 使用CMake和Visual Studio搭建工程并引入OpenCV库

    前言 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 在之前的Windows平台下OpenCV的编译与安装 Mega Li的博客 CSDN博客 nbsp 中介绍了Windows平台中使用CMake编译Open
  • UART通信中流控RTS和CTS的理解

    一 流控 xff0c 顾名思义就是流量控制的意思 目的是协调收发双方 xff0c 使数据不会丢失 如果UART只有RX TX两个信号 xff0c 要流控的话只能是软流控 xff1b 如果有RX xff0c TX xff0c CTS xff0
  • JVM虚拟机栈

    虚拟机栈 每个线程在创建时都会创建一个虚拟机栈 xff0c 其内部保存一个个栈帧 xff0c 对应一次次java方法的调用 xff08 线程私有 xff09 生命周期与线程一致 作用 xff1a 主管java线程的运行 xff0c 保存局部