【jvm】虚拟机栈之局部变量表

目录

        • 一、说明
        • 二、代码分析
          • 2.1 代码示例
          • 2.2 执行javap
          • 2.3 jclasslib插件查看
        • 三、对slot的理解
          • 3.1 说明
          • 3.2 slot索引图
          • 3.3 实例方法的局部变量表
          • 3.4 long和double类型变量占2个slot
        • 四、slot的重复利用
          • 4.1 说明
          • 4.2 变量c复用变量b的槽位
        • 五、静态变量与局部变量对比

一、说明
  • 1.Local Variables
  • 2.局部变量表也被称为局部变量组或本地变量表
  • 3.定义为一个数字数组,主要用于存储方法参数和定义在方法体内的局部变量,这些数据类型包括各类基本数据类型、对象引用(reference),以及returnAddress类型
  • 4.由于局部变量表是建立在线程的栈上,是线程的私有数据,因此不存在数据安全问题
  • 5.局部变量表所需的容量大小是在编译期确定下来的,并保存在方法的Code属性的maximum local variables数据项中。在方法运行期间是不会改边局部变量表的大小的,因为在java代码编译后就已经确定了
  • 6.方法嵌套调用的次数由栈的大小决定。一般来说,栈越大,方法嵌套调用次数越多。对一个函数而言,它的参数和局部变量越多,使得局部变量表膨胀,它的栈帧就越大,以满足方法调用所需传递的信息增大的需求,函数调用就会占用更多的栈空间,导致其嵌套调用次数就会减少
  • 7.局部变量表中的变量只在当前方法调用中有效。在方法执行时,虚拟机通过使用局部变量表完成参数值到参数变量列表的传递过程。当方法调用结束后,随着方法栈帧的销毁,局部变量表也随之销毁
二、代码分析
2.1 代码示例
package com.learning.stack.local_variables;/*** @Author wangyouhui* @Description 局部变量表测试**/
public class LocalVariableTest {public static void main(String[] args) {LocalVariableTest localVariableTest = new LocalVariableTest();int num = 10;localVariableTest.print();}private void print() {System.out.println("局部变量表");}
}
2.2 执行javap
  • 1.执行javap -v StackOverflowErrorLearning.class
Classfile /F:/jdk-learning/jvm/target/classes/com/learning/stack/local_variables/LocalVariableTest.classLast modified 2023-10-16; size 785 bytesMD5 checksum e16aaaceec49515090d5cb15e4c6467aCompiled from "LocalVariableTest.java"
public class com.learning.stack.local_variables.LocalVariableTestminor version: 0major version: 52flags: ACC_PUBLIC, ACC_SUPER
Constant pool:#1 = Methodref          #8.#26         // java/lang/Object."<init>":()V#2 = Class              #27            // com/learning/stack/local_variables/LocalVariableTest#3 = Methodref          #2.#26         // com/learning/stack/local_variables/LocalVariableTest."<init>":()V#4 = Methodref          #2.#28         // com/learning/stack/local_variables/LocalVariableTest.print:()V#5 = Fieldref           #29.#30        // java/lang/System.out:Ljava/io/PrintStream;#6 = String             #31            // 局部变量表#7 = Methodref          #32.#33        // java/io/PrintStream.println:(Ljava/lang/String;)V#8 = Class              #34            // java/lang/Object#9 = Utf8               <init>#10 = Utf8               ()V#11 = Utf8               Code#12 = Utf8               LineNumberTable#13 = Utf8               LocalVariableTable#14 = Utf8               this#15 = Utf8               Lcom/learning/stack/local_variables/LocalVariableTest;#16 = Utf8               main#17 = Utf8               ([Ljava/lang/String;)V#18 = Utf8               args#19 = Utf8               [Ljava/lang/String;#20 = Utf8               localVariableTest#21 = Utf8               num#22 = Utf8               I#23 = Utf8               print#24 = Utf8               SourceFile#25 = Utf8               LocalVariableTest.java#26 = NameAndType        #9:#10         // "<init>":()V#27 = Utf8               com/learning/stack/local_variables/LocalVariableTest#28 = NameAndType        #23:#10        // print:()V#29 = Class              #35            // java/lang/System#30 = NameAndType        #36:#37        // out:Ljava/io/PrintStream;#31 = Utf8               局部变量表#32 = Class              #38            // java/io/PrintStream#33 = NameAndType        #39:#40        // println:(Ljava/lang/String;)V#34 = Utf8               java/lang/Object#35 = Utf8               java/lang/System#36 = Utf8               out#37 = Utf8               Ljava/io/PrintStream;#38 = Utf8               java/io/PrintStream#39 = Utf8               println#40 = Utf8               (Ljava/lang/String;)V
{public com.learning.stack.local_variables.LocalVariableTest();descriptor: ()Vflags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 7: 0LocalVariableTable:Start  Length  Slot  Name   Signature0       5     0  this   Lcom/learning/stack/local_variables/LocalVariableTest;public static void main(java.lang.String[]);descriptor: ([Ljava/lang/String;)Vflags: ACC_PUBLIC, ACC_STATICCode:stack=2, locals=3, args_size=10: new           #2                  // class com/learning/stack/local_variables/LocalVariableTest3: dup4: invokespecial #3                  // Method "<init>":()V7: astore_18: bipush        1010: istore_211: aload_112: invokespecial #4                  // Method print:()V15: returnLineNumberTable:line 9: 0line 10: 8line 11: 11line 12: 15LocalVariableTable:Start  Length  Slot  Name   Signature0      16     0  args   [Ljava/lang/String;8       8     1 localVariableTest   Lcom/learning/stack/local_variables/LocalVariableTest;11       5     2   num   I
}
SourceFile: "LocalVariableTest.java"
  • 2.图示说明
    在这里插入图片描述
2.3 jclasslib插件查看
  • 1.字节码
    在这里插入图片描述

  • 2.异常表
    在这里插入图片描述

  • 3.杂项
    在这里插入图片描述

  • 4.slot槽位
    在这里插入图片描述

三、对slot的理解
3.1 说明
  • 1. 参数值的存放总是在局部变量数组的index0开始,到数组长度-1的索引结束
  • 2. 局部变量表,最基本的存储单元是slot(变量槽)
  • 3. 局部变量表中存放编译器可知的各种基本数据类型(8种),引用类型(reference),returnAddress类型的变量
  • 4.在局部变量表里,32位以内的类型只占用一个slot(包括returnAddress类型),64位的类型(long和double)占用两个slot
  • 5.byte、short、char在存储前被转换为int,boolean也被转为int,0表示false,非0表示true
  • 6. long和double则占据两个slot
  • 7. float占1个slot
  • 8. 引用类型也是32位,占1个slot
  • 9. jvm会为局部变量表中的每一个slot都分配一个访问索引,通过这个索引即可成功访问到局部变量表中指定的局部变量值
  • 10. 当一个实例方法被调用的时候,它的方法参数和方法体内部定义的局部变量将会按照顺序被复制到局部变量表中的每一个slot上
  • 11. 如果需要访问局部变量表中一个64bit的局部变量值时,只需要使用前一个索引即可。比如访问long或double类型变量
  • 12. 如果当前帧是由构造方法或者实例方法创建的,该对象引用this将会存放在index为0的slot处,其余的参数按照参数表顺序继续排列
  • 13. 静态方法中不能用this,是因为静态方法的局部变量表中没有this变量。构造方法和类实例方法的本地变量表index为0的slot处会存放this变量
3.2 slot索引图

在这里插入图片描述

3.3 实例方法的局部变量表

在这里插入图片描述

3.4 long和double类型变量占2个slot

在这里插入图片描述

四、slot的重复利用
4.1 说明
  • 1.栈帧中的局部变量表中的槽位是可以重复利用的
  • 2.如果一个局部变量过了其作用域,在其作用域之后申明的新的局部变量有可能会复用过期的局部变量的槽位,达到节省资源空间的目的
4.2 变量c复用变量b的槽位

在这里插入图片描述

五、静态变量与局部变量对比
  • 1. 参数表分配完毕之后,再根据方法体内定义的变量的顺序和作用域分配
  • 2. 类变量表有两次初始化的机会,第一次是在准备阶段,执行系统初始化,对类变量设置零值,第二次是在初始化阶段,赋予程序员在代码中定义的初始值
  • 3. 局部变量表不存在系统初始化的过程,一旦定义了局部变量则必须程序员来初始化,否则无法使用
  • 4.下面代码是错误的,没有赋值不能使用
    在这里插入图片描述
  • 5. 成员变量在使用前,都经历过默认初始化赋值
  • 6. 成员变量中的类变量在linking的prepare阶段给类变量默认赋值,initial阶段给类变量显示赋值即静态代码块赋值
  • 7. 成员变量中的实例变量随着对象
  • 8. 局部变量在使用前必须要进行显示赋值,否则编译不通过
  • 9.在栈帧中,与性能调优关系最为密切的部分是局部变量表,虚拟机使用局部变量表完成方法的传递
  • 10.局部变量表中的变量是重要的垃圾回收根节点,只要被局部变量表中直接或间接引用的对象都不会被回收

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AQS中lock源码解析

什么是AQS&#xff1f; 就是基于双向链表CAS实现的锁的一种机制或者方法思想。就是AbstractQueuedSynchronizer&#xff0c;是Java并发包下的一个基类基于AQS实现的同步器包括&#xff1a;ReentrantLock、CountDownLatch、Samaphone、FutureTask、ReentrantWriteLock Abstrac…

如何用记事本制作一个简陋的小网页(3)——注册信息表

目录 前提须知&#xff1a; 一、表格建立之前&#xff1a; 二、表格的建立&#xff1a; 三、信息表的内容填充&#xff1a; 1.昵称 和 电话 &#xff1a; 2.密码&#xff1a; 3.性别&#xff1a; 4. 爱好&#xff1a; 5.民族&#xff1a; 6. 出生日期&#xff1a; 7.…

Linux远程管理工具

Linux远程管理服务器多基于 SSH 协议。本节给大家介绍 2 种常见的基于 SSH 协议的远程管理工具&#xff0c;分别是 PuTTY 和 SecureCRT。 在使用远程管理工具之前&#xff0c;应先设置宿主机 Windows 与虚拟机 Linux 能够连通。 这里要注意 VMware 的网卡设置&#xff0c;Lin…

怎么把图片转换成ico图标文件?

环境&#xff1a; Win10 专业版 问题描述&#xff1a; 怎么把图片转换成ico图标文件 解决方案&#xff1a; 要将图片转换为 ico 图标文件&#xff0c;可以使用以下几种方法&#xff1a; 方法 1&#xff1a;使用在线转换器 1.访问在线 ico 转换器&#xff0c;例如&#xf…

EtherNet/IP转Modbus TCP协议网关的接口

远创智控的YC-EIPM-TCP网关产品&#xff0c;它有什么作用呢&#xff1f;一起来了解一下吧&#xff01; 远创智控YC-EIPM-TCP网关产品可以通过各种数据接口和工业领域的仪表、PLC、计量设备等产品连接&#xff0c;实时采集这些设备中的运行数据、状态数据等信息&#xff0c;并把…

STM32 HAL库高级定时器输入捕获脉宽测量

STM32 HAL库高级定时器输入捕获脉宽测量 &#x1f4cc;相关篇《STM32 HAL库定时器输入捕获SlaveMode脉宽测量》 ✨相比于上面所使用的高级定时器输入捕获从模式来测量PWM信号&#xff0c;实现方法更为复杂一下&#xff0c;但是还是将实现的方法记录下来。 &#x1f4cc;本篇实现…

0基础学习PyFlink——Map和Reduce函数处理单词统计

在很多讲解大数据的案例中&#xff0c;往往都会以一个单词统计例子来抛砖引玉。本文也不免俗&#xff0c;例子来源于PyFlink的《Table API Tutorial》&#xff0c;我们会通过几种方式统计不同的单词出现的个数&#xff0c;从而达到循序渐进的学习效果。 常规方法 # input.py …

正点原子嵌入式linux驱动开发——pinctrl和gpio子系统

在上一篇笔记中&#xff0c;学习编写了基于设备树的LED驱动&#xff0c;但是驱动的本质还是没变&#xff0c;都是配置LED灯 所使用的GPIO寄存器&#xff0c;驱动开发方式和裸机基本没区别。Linux是一个庞大而完善的系统&#xff0c;尤其是驱动框架&#xff0c;像GPIO这种最基本…

二叉树,堆排序及TopK问题

要讲二叉树的概念&#xff0c;就要先讲树的概念。 树是什么呢&#xff1f; 树其实是一种储存数据的结构&#xff0c;因为他的结构倒过来和生活中的树很相似所以才被称之为树。 这是一颗多叉树&#xff0c;从最顶端的节点可以找到下边的几个节点&#xff0c;下边的节点又可以找…

Chrome插件精选 — 标签效率管理插件

Chrome实现同一功能的插件往往有多款产品&#xff0c;逐一去安装试用耗时又费力&#xff0c;在此为某一类型插件挑选出比较好用的一款或几款&#xff0c;尽量满足界面精致、功能齐全、设置选项丰富的使用要求&#xff0c;便于节省一个个去尝试的时间和精力。 1. OneTab Plus 下…

从0-1,使用腾讯OCR进行身份证识别

目录 1.申请腾讯OCR权限 2.代码思路 3.Postman测试​ 1.申请腾讯OCR权限 获取 secretId 和 secretKey&#xff0c;见上文从0到1&#xff0c;申请cos服务器并上传图片到cos文件服务器-CSDN博客https://blog.csdn.net/m0_55627541/article/details/133902798 2.代码思路 入参…

【PXIE301-211】青翼科技基于PXIE总线的16路并行LVDS数据采集、1路光纤数据收发处理平台

板卡概述 PXIE301-211是一款基于PXIE总线架构的16路并行LVDS数据采集、1路光纤收发处理平台&#xff0c;该板卡采用Xilinx的高性能Kintex 7系列FPGA XC7K325T作为实时处理器&#xff0c;实现各个接口之间的互联。板载1组64位的DDR3 SDRAM用作数据缓存。板卡具有1个FMC&#xf…

2023_Spark_实验十四:SparkSQL入门操作

1、将emp.csv、dept.csv文件上传到分布式环境&#xff0c;再用 hdfs dfs -put dept.csv /input/ hdfs dfs -put emp.csv /input/ 将本地文件put到hdfs文件系统的input目录下 2、或者调用本地文件也可以。区别&#xff1a;sc.textFile("file:///D:\\temp\\emp.csv&qu…

OpenLDAP LDIF详解

手把手一步步搭建LDAP服务器并加域 有必要理解的概念LDAPWindows Active Directory 服务器配置安装 OpenLDAP自定义安装修改对象&#xff08;用户和分组等&#xff09;修改olcSuffix 和 olcRootDN 属性增加olcRootPW 属性修改olcAccess属性验证新属性值 添加对象&#xff08;用…

【C语言必知必会 | 第四篇】一文带你精通顺序结构

引言 C语言是一门面向过程的、抽象化的通用程序设计语言&#xff0c;广泛应用于底层开发。它在编程语言中具有举足轻重的地位。 此文为【C语言必知必会】系列第四篇&#xff0c;进行C语言顺序结构的专项练习&#xff0c;结合专题优质题目&#xff0c;带领读者从0开始&#xff0…

[人工智能-综述-12]:第九届全球软件大会(南京)有感 -1-程序员通过大模型增强自身软件研发效率的同时,也在砸自己的饭碗

目录 前言&#xff1a; 一、什么是软件工程 1.1 什么软件工程 1.2 影响软件开发效能的三大因素 1.3 AI大模型是如何提升软件工程全过程效率的 二、AI大模型如何提升软件项目管理效率 2.1 概述 2.2 案例或工具 三、AI大模型如何提升软件开发工具的效率 3.1 概述 3.2 …

Git GUI使用笔记

看这个视频 Git GUI基本使用_哔哩哔哩_bilibili 1 下载 Git-2.42.0.2-64Window64位安装包-最新版资源-CSDN文库 安装软件就一路next就可以 2 配置 空白处右键&#xff0c;选择Open Git Bash here &#xff0c;输入下面两行配置信息 git config --global user.name "Y…

小程序之自定义组件 结合案例(会议OA的会议/投票管理及个人中心的搭建)详解 (4)

⭐⭐ 小程序专栏&#xff1a;小程序开发专栏 ⭐⭐ 个人主页&#xff1a;个人主页 目录 一.前言 二.小程序自定义组件及其使用 2.1 自定义组件的使用 三.使用自定义组件完成会议功能界面的实现 3.1 导航栏的实现 3.2 会议界面内容的实现 四.投票管理界面 五.个人中心 今天…

uview组件使用笔记

图标样式 修改图标的样式 通过color参数修改图标的颜色通过size参数修改图标的大小&#xff0c;单位为rpx 效果图 <u-icon name"photo" color"#2979ff" size"28"></u-icon>图片图标 1.3.0 这里说的图片图标&#xff0c;指的是小…