【转帖】16.JVM栈帧内部结构-局部变量表

jvm,内部结构,局部变量 · 浏览次数 : 0

小编点评

**1.局部变量表(Local variables)** *局部变量表是一种数字数组,用于存储方法参数和定义在方法体内的局部变量。 * 编译器在编译时期确定局部变量表的大小。 * 局部变量表存储了三个变量,分别为 `args`、`test` 和 `num`。 * 每个局部变量都有大小定,即 `int` 类型。 * 局部变量表的大小在编译时期确定,不会随着程序运行改变。 **2. 局部变量表定义** * 局部变量表是一个动态数组,位于栈帧中。 * 每个局部变量都有一条指向其存储位置的指针。 * 局部变量表可以被多个方法共享。 **3. 局部变量的用途** * 局部变量用于存储方法参数和临时变量。 * 它们可以被方法调用传递,并在方法执行过程中使用。 * 局部变量表有助于优化方法调用,减少方法参数和局部变量的创建。 **4. 局部变量大小** * 在编译时期,局部变量表的大小被确定。 * 编译器根据方法参数和局部变量的类型和数量计算出大小。 * 即使方法参数或局部变量数量发生变化,局部变量表也不会改变。 **5. 方法嵌套调用的局部变量表** * 方法嵌套调用会导致局部变量表的大小增加。 * 因为虚拟机使用局部变量表完成方法传递,栈帧越大,方法嵌套调用的次数就越多。 * 局部变量表中的变量只在当前方法中有效,当方法调用结束后,随着方法栈帧的销毁,局部变量表也会随之销毁。

正文

1.局部变量表(Local variables)

1.局部变量表也称为局部变量数组或本地变量表。
2.局部变量表定义为一个数字数组,主要用于存储方法参数和定义在方法体内的局部变量。(局部变量表的作用)
3.局部变量表示栈帧中的数据,栈帧被线程私有,所以不存在线程安全的问题,也就是多线程之间不会相互影响。(这里并不是绝对的,其实有可能出现线程安全问题,参考https://blog.csdn.net/u011069294/article/details/107157140
4.局部变量表的大小在编译时期确定。一旦确定,就不会再改变。
在这里插入图片描述
查看局部变量表:将下面的java代码产生的class文件使用javap进行反编译。

public class LocalVariablesTest {
    public static void main(String[] args) {
        LocalVariablesTest test = new LocalVariablesTest();
        int num = 10;
    }
}

    找到生成的LocalVariablesTest.class文件,使用javap -v LocalVariablesTest, 输出如下,最下面有一个LocalVariableTable就是局部变量表。
    可以看到局部变量表存储了三个变量,分别为args,test,num。并且都有大小solt。总共加起来的solt是3。这里就可以看出来,局部变量表的大小是在编译器确定的。因为我们只是反编译了class文件,就能够看到局部变量表以及它的大小。

    D:\Eclipse_workspace\JVM\jvn\bin\jvn>javap -v LocalVariablesTest
    Classfile /D:/Eclipse_workspace/JVM/jvn/bin/jvn/LocalVariablesTest.class
      Last modified 2020-7-1; size 466 bytes
      MD5 checksum 24673853d3865f4d8d0bab8ca5b3435b
      Compiled from "LocalVariablesTest.java"
    public class jvn.LocalVariablesTest
      minor version: 0
      major version: 52
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Class              #2             // jvn/LocalVariablesTest
       #2 = Utf8               jvn/LocalVariablesTest
       #3 = Class              #4             // java/lang/Object
       #4 = Utf8               java/lang/Object
       #5 = Utf8               <init>
       #6 = Utf8               ()V
       #7 = Utf8               Code
       #8 = Methodref          #3.#9          // java/lang/Object."<init>":()V
       #9 = NameAndType        #5:#6          // "<init>":()V
      #10 = Utf8               LineNumberTable
      #11 = Utf8               LocalVariableTable
      #12 = Utf8               this
      #13 = Utf8               Ljvn/LocalVariablesTest;
      #14 = Utf8               main
      #15 = Utf8               ([Ljava/lang/String;)V
      #16 = Methodref          #1.#9          // jvn/LocalVariablesTest."<init>":()V
      #17 = Utf8               args
      #18 = Utf8               [Ljava/lang/String;
      #19 = Utf8               test
      #20 = Utf8               num
      #21 = Utf8               I
      #22 = Utf8               SourceFile
      #23 = Utf8               LocalVariablesTest.java
    {
      public jvn.LocalVariablesTest();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1
             0: aload_0
             1: invokespecial #8                  // Method java/lang/Object."<init>":()V
             4: return
          LineNumberTable:
            line 3: 0
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0       5     0  this   Ljvn/LocalVariablesTest;
    

    public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
    stack=2, locals=3, args_size=1
    0: new #1 // class jvn/LocalVariablesTest
    3: dup
    4: invokespecial #16 // Method "<init>"😦)V
    7: astore_1
    8: bipush 10
    10: istore_2
    11: return
    LineNumberTable:
    line 5: 0
    line 6: 8
    line 7: 11
    LocalVariableTable: // 局部变量表,可以看到局部变量表存储了三个变量,分别为args,test,num。并且都有大小solt。总共加起来的solt是3。这里就可以看出来,局部变量表的大小是在编译期确定的。因为我们只是反编译了class文件,就能够看到局部变量表以及它的大小。
    Start Length Slot Name Signature
    0 12 0 args [Ljava/lang/String;
    8 4 1 test Ljvn/LocalVariablesTest;
    11 1 2 num I
    }
    SourceFile: "LocalVariablesTest.java"

      5.方法嵌套调用的次数由栈的大小决定。栈越大,方法嵌套调用的次数越多。一个方法,参数和局部变量越多,栈帧就越大,函数调用占用的栈空间就越大,其能够嵌套调用的次数就越少。
      6.局部变量表中的变量只在当前方法中有效。当方法调用结束后,随着方法栈帧的销毁,局部变量表也会随之销毁。
      在这里插入图片描述
      局部变量表补充说明:
      1.在栈帧中,与性能调优关系最为密切的部分就是前面提到的局部变量表。在方法执行时,虚拟机使用局部变量表完成方法的传递。
      2.局部变量表中的变量也是重要的垃圾回收根节点,只要被局部变量表中直接或间接引用的对象都不会被回收。
      在这里插入图片描述

      更多JVM文章请参考我的JVM专栏:https://blog.csdn.net/u011069294/category_10113093.html

      文章知识点与官方知识档案匹配,可进一步学习相关知识

      与【转帖】16.JVM栈帧内部结构-局部变量表相似的内容:

      【转帖】16.JVM栈帧内部结构-局部变量表

      目录 1.局部变量表(Local variables) 1.局部变量表(Local variables) 1.局部变量表也称为局部变量数组或本地变量表。 2.局部变量表定义为一个数字数组,主要用于存储方法参数和定义在方法体内的局部变量。(局部变量表的作用) 3.局部变量表示栈帧中的数据,栈帧被线程私

      【转帖】JVM 内存模型与垃圾回收

      文章目录 1. JVM内存模型1.1. 程序计数器 (线程私有)1.2. Java 虚拟机栈 (线程私有)1.3. 本地方法栈 (线程私有)1.4. Java 堆 (线程共享)1.5. 方法区 (线程共享)1.6. 运行时常量池 (线程共享)1.7. 直接内存 (堆外内存) 2. 垃圾查找算法2.1

      [转帖]【技术剖析】16. Native Memory Tracking 详解(2):追踪区域分析(一)

      https://bbs.huaweicloud.com/forum/thread-0295101552606827089-1-1.html 上篇文章 Native Memory Tracking 详解(1):基础介绍 中,分享了如何使用NMT,以及NMT内存 & OS内存概念的差异性,本篇将介绍NM

      [转帖]Redis 7 参数 修改 说明

      2022-06-16 14:491800原创Redis 本文链接:https://www.cndba.cn/dave/article/108066 在之前的博客我们介绍了Redis 7 的安装和配置,如下: Linux 7.8 平台 Redis 7 安装并配置开机自启动 操作手册https://ww

      [转帖]Redis 备份与恢复(RDB/AOF) 说明

      2022-06-16 20:364580原创Redis 本文链接:https://www.cndba.cn/dave/article/108068 1 RDB 方式 1.1 RDB 备份恢复说明 Redis 的备份恢复有两种方法:RDB和AOF。 其中RDB 文件是一个经过压缩的二进制文件,有两个R

      [转帖]postgresql 物理备份 barman 之 安装

      os: ubuntu 16.04postgresql: 9.6.8barman: 2.5 ip 规划 192.168.56.101 node1 barman192.168.56.102 node2 postgresql barman 是2ndquadrant推出的一款 postgresql 开源备份

      [转帖]Redis 7.0 三节点哨兵(Sentinel)高可用 环境搭建手册

      2022-06-17 16:253480原创Redis 本文链接:https://www.cndba.cn/dave/article/108088 1 哨兵高可用架构说明 Redis 最早的高可用方案是主从复制,但这种方案存在一个问题,就是当主库宕机后,从库不会自动切成主库,需要人工干预。 所有在主

      [转帖]分布式数据库中间件:MyCat 和 ShardingSphere 对比说明

      2022-05-29 16:537540转载MySQL 原文链接:https://blog.csdn.net/horses/article/details/106086208 本文转载自 https://blog.csdn.net/horses/article/details/106086208 今

      [转帖]SQL Server 体系结构中的2个主要引擎 说明

      2020-03-18 16:2321450原创SQLServer 本文链接:https://www.cndba.cn/dave/article/4498 SQL Server 由两个主要引擎组成∶关系引擎(relational engine)和存储引擎(storage engine)。 1 关系引擎

      [转帖]Perf IPC以及CPU性能

      https://plantegg.github.io/2021/05/16/Perf_IPC%E4%BB%A5%E5%8F%8ACPU%E5%88%A9%E7%94%A8%E7%8E%87/ 为了让程序能快点,特意了解了CPU的各种原理,比如多核、超线程、NUMA、睿频、功耗、GPU、大小核再到分支