`
wangwengcn
  • 浏览: 176217 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

栈帧、局部变量表、操作数栈

    博客分类:
  • JVM
阅读更多

1.定义
     栈帧(stack frame)是用于支持虚拟机进行方法调用和方法执行的数据结构,它是虚拟机运行时数据区中的虚拟机栈的栈元素。栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。
     每一个方法从调用开始到执行完成的过程,就对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程。
     对于执行引擎来说,活动线程中,只有栈顶的栈帧是有效的,称为当前栈帧,这个栈帧所关联的方法称为当前方法。执行引擎所运行的所有字节码指令都只针对当前栈帧进行操作。

 

 

2.组成
 (1)局部变量表
      局部变量表是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。在Java程序被编译成Class文件时,就在方法的Code属性的max_locals数据项中确定了该方法所需要分配的
      最大局部变量表的容量。
      局部变量表的容量以变量槽(Slot)为最小单位,32位虚拟机中一个Slot可以存放一个32位以内的数据类型(boolean、byte、char、short、int、float、reference和returnAddress八种)。
      reference类型虚拟机规范没有明确说明它的长度,但一般来说,虚拟机实现至少都应当能从此引用中直接或者间接地查找到对象在Java堆中的起始地址索引和方法区中的对象类型数据。
      returnAddress类型是为字节码指令jsr、jsr_w和ret服务的,它指向了一条字节码指令的地址。
      虚拟机是使用局部变量表完成参数值到参数变量列表的传递过程的,如果是实例方法(非static),那么局部变量表的第0位索引的Slot默认是用于传递方法所属对象实例的引用,在方法中通过this访问。
      Slot是可以重用的,当Slot中的变量超出了作用域,那么下一次分配Slot的时候,将会覆盖原来的数据。Slot对对象的引用会影响GC(要是被引用,将不会被回收)。
  系统不会为局部变量赋予初始值(实例变量和类变量都会被赋予初始值)。也就是说不存在类变量那样的准备阶段。
 (2)操作数栈
      Java虚拟机的解释执行引擎被称为"基于栈的执行引擎",其中所指的栈就是指-操作数栈。
      操作数栈也常被称为操作栈。
     和局部变量区一样,操作数栈也是被组织成一个以字长为单位的数组。但是和前者不同的是,它不是通过索引来访问,而是通过标准的栈操作—压栈和出栈—来访问的。比如,如果某个指令把一个值压入到操作数栈中,稍后另一个指令就可以弹出这个值来使用。
      虚拟机在操作数栈中存储数据的方式和在局部变量区中是一样的:如int、long、float、double、reference和returnType的存储。对于byte、short以及char类型的值在压入到操作数栈之前,也会被转换为int。
      虚拟机把操作数栈作为它的工作区——大多数指令都要从这里弹出数据,执行运算,然后把结果压回操作数栈。比如,iadd指令就要从操作数栈中弹出两个整数,执行加法运算,其结果又压回到操作数栈中,看看下面的示例,它演示了虚拟机是如何把两个int类型的局部变量相加,再把结果保存到第三个局部变量的:
  

begin
iload_0    // push the int in local variable 0 onto the stack
iload_1    // push the int in local variable 1 onto the stack
iadd       // pop two ints, add them, push result
istore_2   // pop int, store into local variable 2
end

 
      在这个字节码序列里,前两个指令iload_0和iload_1将存储在局部变量中索引为0和1的整数压入操作数栈中,其后iadd指令从操作数栈中弹出那两个整数相加,再将结果压入操作数栈。第四条指令istore_2则从操作数栈中弹出结果,并把它存储到局部变量区索引为2的位置。下图详细表述了这个过程中局部变量和操作数栈的状态变化,图中没有使用的局部变量区和操作数栈区域以空白表示。
  


  

分享到:
评论
6 楼 空城回转 2018-01-13  
永洁童心 写道
最后的图中,在afterload_1步骤中,operand stack中的顺序是不是应该98在上面,100在下面啊?
先把变量0入栈,再变量1入栈,应该是98,100吧

操作数栈是向下增长的,栈顶在最底部。
5 楼 永洁童心 2017-11-09  
最后的图中,在afterload_1步骤中,operand stack中的顺序是不是应该98在上面,100在下面啊?
先把变量0入栈,再变量1入栈,应该是98,100吧
4 楼 a492846462 2016-12-01  
    
3 楼 projim_tao 2016-11-25  
感谢楼主了,写得还是比较详细了,解答了我关于局部变量区和操作数栈的疑惑。
2 楼 wangwengcn 2015-12-20  
manxisuo 写道
写的非常好,谢谢博主。

难得有人光临我的博客
1 楼 manxisuo 2015-05-14  
写的非常好,谢谢博主。

相关推荐

    xiaozhengyu#StudyNotes#8.2.1局部变量表1

    栈帧中存储的数据大致有:局部变量表、操作数栈、动态连接、方法返回地址图1 虚拟机运行时数据区域图2 栈帧的结构2. 局部变量表的说明局部变量表(Local Va

    函数如何调用:出入Java栈1

    本文将深入探讨Java中的函数调用机制,重点关注Java堆、局部变量表、操作数栈、帧数据区以及栈上分配等核心概念。 首先,Java堆是JVM(Java虚拟机)内存模型的一部分,主要用来存储对象实例。当一个对象被创建时,...

    15.运行时栈帧结构1

    栈帧中包括了局部变量表、操作数栈、动态链接、方法返回地址和一些额外的附加信息。 局部变量表是栈帧中的一组变量的存储空间,用于存放方法参数和方法内部定义的局部变量。在Java编程时,就在方法的Code属性中的...

    Java虚拟机栈--栈帧.docx

    局部变量表的变量仅在当前方法调用内有效,当方法执行结束,栈帧销毁,局部变量表也随之消失。局部变量表的槽位可以被复用,一旦一个变量超出其作用域,其槽位可能被后续声明的变量占用,以节省资源。 理解Java...

    JVM中[虚拟机栈]的所有内容-pdf

    栈帧是一个内存区块,包含了多个数据结构,如局部变量表、操作数栈、动态链接、方法返回地址以及一些额外的信息。这些数据结构共同协作,确保了Java方法的正常执行。 1. 局部变量表(Local Variables Table):这是...

    5 运行时数据区之虚拟机栈.md,学习代码i

    栈的主要任务是存储方法调用过程中的局部变量表、操作数栈、动态链接和方法出口等信息。这些信息是Java方法执行的基础。 局部变量表存放了各种基本类型(如int、float、boolean)、对象引用和返回地址。当一个方法...

    深入理解JVM-java虚拟机栈.docx

    栈的主要任务是为每个方法的执行提供一个栈帧(Stack Frame),栈帧存储了方法执行过程中的局部变量、操作数栈、动态连接和方法返回地址等关键信息。 栈帧是虚拟机栈的元素,它包含了以下几个重要组成部分: 1. ...

    Java栈详解Java栈详解.doc

    - **栈帧结构**:栈是通过栈帧来组织的,每个栈帧包含局部变量区、操作数栈和帧数据区。 - **数据私有性**:每个线程只能访问自己的栈,不会存在多线程数据共享问题,无需考虑同步。 2. **栈帧的组成部分** - **...

    4_JVM_8~11章.pdf

    当执行Java程序源码时,编译器会计算出栈帧中局部变量表和操作数栈所需的大小,并将这些信息写入方法表的Code属性中。 #### 3. 运行时栈帧结构 每个方法调用都对应一个栈帧(Stack Frame),这个栈帧包含以下几个...

    深入java虚拟机(一)——java虚拟机底层结构详解1

    3. **当前执行环境指针(Frame Pointer)**:指向当前执行的方法的栈帧,栈帧是方法执行的逻辑单元,包含了局部变量、操作数栈以及方法返回地址等信息。 4. **局部变量指针(Variables Pointer)**:指向当前方法的...

    Java虚拟机(字节码的应用)1

    例如,`iload` 指令用于将局部变量表中的一个int值加载到操作数栈。 2. **局部变量表**:每个方法都有自己的局部变量表,用于存储方法参数和局部变量。在方法调用时,参数会被放入局部变量表,如例子中的`this`引用...

    02.Java虚拟机栈1

    `时,会先将1和2分别压入操作数栈,然后将栈顶两个元素相加,结果再入栈,最后存入局部变量表中a的位置。 3. **动态链接**(Dynamic Linking):这部分存储了指向当前方法所属类的常量池的引用,使得方法能调用到...

    java中方法重载内存分析

    当一个方法被调用时,JVM会在栈内存中创建一个栈帧(Stack Frame),这个栈帧包含了局部变量表、操作数栈、动态链接和方法返回地址等信息。对于方法重载,每次调用不同的重载方法,都会在栈上创建一个新的栈帧,每个...

    6.1.2.JVM进行篇笔记1

    栈帧包含了方法执行所需的所有信息,如局部变量表、操作数栈、动态链接、方法返回地址等。局部变量表用于存储方法的局部变量和参数,操作数栈则用于计算和临时存储数据。动态链接指的是栈帧对运行时常量池的引用,...

    java之jvm学习笔记十而(访问控制器的栈校验机制)-步骤2源码

    2. **栈帧布局**:栈帧是JVM线程执行方法时的工作区域,包含局部变量表、操作数栈、动态链接、方法返回地址等。在步骤2,我们可能看到对栈帧布局的检查,确保操作数栈的深度正确,以容纳所有的操作数。 3. **权限...

    Java内存模型中的虚拟机栈原理分析

    在栈帧中包括局部变量表、操作数栈、指向当前方法所属的类的运行时常量池的引用、方法返回地址和一些额外的附加信息。 局部变量表是用于存储方法中的局部变量的,包括在方法中声明的非静态变量以及函数形参。对基本...

    JVM入门解析.pptx

    每个线程的虚拟机栈中会根据方法调用创建栈帧,例如`Thread1`的`run()`方法和`Thread2`的`run()`方法各有各自的栈帧,栈帧中包含局部变量表、操作数栈等信息。 在`Thread1.run()`中,局部变量`a`、`b`和`c`会被存储...

    Java虚拟机规范8

    - **帧**:表示一个线程上的一个栈帧,包含局部变量表、操作数栈、动态链接信息以及返回地址等。 - **局部变量表**:用于存储方法参数和方法内部定义的局部变量。 - **操作数栈**:用于存储临时结果,并作为操作数栈...

    JVM内存模型一些简单的概述

    栈帧中包含了局部变量表、操作数栈、动态链接以及方法返回地址等信息。局部变量表用于存储方法参数和局部变量,操作数栈处理计算操作,动态链接用于调用方法,而方法出口信息则在方法结束时使用。虚拟机栈可能出现两...

    JVM指令手册.docx

    每个方法调用在JVM中都会创建一个栈帧,包含了局部变量表、操作数栈、动态链接和方法返回地址。局部变量表的大小在编译时确定,每个槽位可以存储一个基本类型或一个对象引用。对于基本类型,如int、float等,它们...

Global site tag (gtag.js) - Google Analytics