理解JVM里的栈信息

文章目录

      • 栈内存的结构
      • 实际例子
        • [局部变量表(Local Variable Array)](#局部变量表(Local Variable Array))
        • [操作数栈(Operand Stack)](#操作数栈(Operand Stack))
        • [动态链接(Dynamic Linking)](#动态链接(Dynamic Linking))
        • [方法返回地址(Return Address)](#方法返回地址(Return Address))
        • 其他信息
      • 调用示意图
      • 问题

栈内存的结构

Java 栈内存主要由多个栈帧(Stack Frame)组成,每个线程都有自己的独立栈内存。每个栈帧对应一次方法调用,包含以下几个部分:

局部变量区(Local Variables):

存储方法的参数、基本数据类型的局部变量以及对象引用(不包括对象本身)。

操作数栈(Operand Stack):

用于执行字节码指令时存储临时数据和计算结果。

动态链接(Dynamic Linking):

方法调用过程中用于支持方法之间的链接和调用。

方法返回地址(Return Address):

指示方法执行完毕后返回到调用者的指令地

实际例子

局部变量表(Local Variable Array)

局部变量表用于存储方法的参数和局部变量。每个变量在表中都有一个索引,通过索引可以快速访问变量值。局部变量表的大小在编译时确定,并且随着方法的调用和返回自动分配和回收。

基本数据类型:如 int、float、double 等,占用固定大小的空间。

引用类型:存储对象的引用(即指向堆中对象的指针)。

长整型和双精度浮点型:在局部变量表中占用两个槽(slot)。

bash 复制代码
public void exampleMethod(int a, double b) {
    int c = a + 5;
    double d = b * 2.0;
}

在上述方法中,局部变量表可能包含以下内容:

索引 内容

bash 复制代码
0	this(如果是实例方法)
1	a(int)
2	b(double,占用索引 2 和 3)
4	c(int)
5	d(double,占用索引 5 和 6)
操作数栈(Operand Stack)

操作数栈用于执行字节码指令时存储临时数据和计算结果。它是一个后进先出(LIFO)的栈,支持各种操作,如加载变量、执行算术运算、方法调用等。

示例:

java

bash 复制代码
复制代码
int a = 10;
int b = 20;
int c = a + b;

对应的字节码操作数栈操作可能如下:

将 a 加载到操作数栈。

将 b 加载到操作数栈。

执行加法操作,将结果压回操作数栈。

将结果存储到局部变量 c。

动态链接(Dynamic Linking)

动态链接用于支持方法调用过程中的符号引用解析。每个栈帧中包含一个指向运行时常量池(Runtime Constant Pool)的指针,用于解析方法调用时的符号引用。

方法返回地址(Return Address)

当一个方法调用另一个方法时,JVM 需要记录调用方法的下一条指令的位置,以便被调用的方法执行完毕后能够返回到正确的位置继续执行。返回地址就是用于存储这一信息的。

其他信息

包括异常处理信息、方法的出入口信息等,用于支持方法执行期间的各种功能。

调用示意图

bash 复制代码
public class StackFrameExample {
    public static void main(String[] args) {
        int result = add(5, 10);
        System.out.println("Result: " + result);
    }

    public static int add(int a, int b) {
        return a + b;
    }
}

最开始的方法在最下面

bash 复制代码
|---------------------------|
| println 方法栈帧          |
|---------------------------|
| add 方法栈帧              |
|---------------------------|
| main 方法栈帧             |
|---------------------------|

问题

  • 那在方法里new 的对象分配在哪里? 实际上还是在堆上,只有基本数据类型会分布在栈上
  • 大致可以估算下,上面的方法可以递归多少次
相关推荐
程序猿进阶38 分钟前
堆外内存泄露排查经历
java·jvm·后端·面试·性能优化·oom·内存泄露
阿龟在奔跑12 小时前
引用类型的局部变量线程安全问题分析——以多线程对方法局部变量List类型对象实例的add、remove操作为例
java·jvm·安全·list
王佑辉13 小时前
【jvm】方法区常用参数有哪些
jvm
王佑辉13 小时前
【jvm】HotSpot中方法区的演进
jvm
Domain-zhuo13 小时前
什么是JavaScript原型链?
开发语言·前端·javascript·jvm·ecmascript·原型模式
Theodore_10222 天前
7 设计模式原则之合成复用原则
java·开发语言·jvm·设计模式·java-ee·合成复用原则
我是苏苏2 天前
Web开发:ORM框架之使用Freesql的DbFrist封装常见功能
java·前端·jvm
天草二十六_简村人2 天前
Java语言编程,通过阿里云mongo数据库监控实现数据库的连接池优化
java·jvm·数据库·mongodb·阿里云·微服务·云计算
老码沉思录2 天前
Android开发实战班 - 数据持久化 - Room 数据库应用
android·jvm·数据库
起名字真南2 天前
【C++】深入理解 C++ 中的继承进阶:多继承、菱形继承及其解决方案
java·jvm·c++·chatgpt·aigc