zoukankan      html  css  js  c++  java
  • java虚拟机规范-运行时栈帧

    前言

    java虚拟机是java跨平台的基石,本文的描述以jdk7.0为准,其他版本可能会有一些微调。

    引用

    栈帧

    • 每当一个java方法被执行时都会在虚拟机中新创建一个栈帧,方法调用结束后即被销毁。
    • 栈帧存储空间为虚拟机栈,每一个栈帧都有自己的局部变量表、操作数栈和指向当前方法所属的类的运行时常量池的引用。
    • 在每个线程中,只有目前正在执行的那个方法的栈帧是活动的。这个栈帧就称为当前栈帧(current frame),这个栈帧对应的方法称之为当前方法(current method)。定义这个方法的类就称之为当前类(current class)。对局部变量表和操作数栈的各种操作,通常都指的是对当前栈帧的局部变量表和操作数栈进行的操作。如下图所示,

    变量

    局部变量

    • 每一个栈帧包含一组局部变量,这组局部变量中包含了方法运行时所需要的所有的变量(含this引用)、方法参数和其他定义的局部变量。局部变量的类型包括以下几种:
      • boolean
      • byte
      • char
      • short
      • int
      • float
      • reference
      • returnAddress
      • long
      • double
    • 除了long和double外,其他所有的变量在局部变量表中都只占一个槽位(slot),而long和double占2个槽位。
    • 特别值得一提的是,当一个实例方法被调用的时候,局部变量表中的第0个局部变量一定是用来存储被调用的实例方法所在的对象引用。(this关键字,可以参考下面示例中的字节码截图),后续的其他参数将会传递至从1开始的局部变量表位置上。
    • 示例:
      • 以下图中的代码为例:
      • 对应的字节码如下:
      • 具体的操作流程示意:
    • 释义:
      • 从上图中我们可以看出例如int x=12,在jvm中对应着两个指令
        • bipush 10,bipush指令用于将一个byte作为一个整型数字插入到操作数栈中(oprand stack),这里将10插入到操作数栈
        • istore_1,istore_1指令(实际上这个应该称之为操作码opcode,指令是指操作码加上操作数oprand)是istore_指令组中的一个,用于将一个整型数字存储到局部变量中,<n>代表的是局部变量表中的存储位置,同时只能为0,1,2,3;超过3了就只能使用istore指令。
      • 注意,istore_1操作码和istore 4指令两者的区别为
        • 前者只是一个操作码,只占一个单位的长度,后者是操作码和操作数组合的指令,占2个单位的长度。(注意看Code中每一行指令前面的数字)
    • 思考:
      • 看了上图的字节码中可能有人会问,为什么还需要istore和iload这两个指令呢?这是因为栈本身不是用来存储数据的,而是用局部变量表来存储。局部变量通过索引寻址。
  • 相关阅读:
    linux安装jenkins
    如何将接口进行限流
    java线程池思想
    一次缓存评估过程
    docker
    linux基本操作
    【安卓】App自动化环境搭建
    sheill之文本处理工具
    Liunx vim编辑器
    Liunx 远程
  • 原文地址:https://www.cnblogs.com/editice/p/5420716.html
Copyright © 2011-2022 走看看