所以我知道存在 2 个内存区域:Stack 和 Heap。
我还知道,如果您创建一个局部变量,它将存在于堆栈中,而不是堆中。随着我们将数据插入堆栈,堆栈将增长,如下所示:
现在我会试着把我遇到的困惑转嫁给你:
例如这个简单的 Java 代码:
public class TestClass {
public static void main(String[] args) {
Object foo = null;
Object bar = null;
}
}
被翻译成这个字节码:
public static void main(java.lang.String[]);
Code:
Stack=1, Locals=3, Args_size=1
0: aconst_null
1: astore_1
2: aconst_null
3: astore_2
4: return
LineNumberTable:
line 5: 0
line 6: 2
line 7: 4
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 args [Ljava/lang/String;
2 3 1 foo Ljava/lang/Object;
4 1 2 bar Ljava/lang/Object;
根据定义 acons_null 是:
push a null reference onto the stack
astore_1 是:
store a reference into local variable 1
我感到困惑的是,我们将 foo 压入堆栈,然后又将其存储在堆栈中?在局部变量中存储引用是什么意思?那个局部变量在哪里?我们将 foo 插入的堆栈还是这些单独的堆栈?
此时,如果我在第一个压入堆栈的对象上调用一个方法,由于堆栈指针指向我压入的最后一个元素,它将如何处理?
最佳答案
在 JVM 中,每个线程都存在一个堆栈。每个堆栈由多个帧组成:每个方法调用都会创建一个新帧,当方法调用完成时,该帧将被销毁。
在栈帧中有两个区域:
- 操作数堆栈(不要将此处的“堆栈”一词与 JVM 堆栈本身混淆——此处的堆栈表示该区域为后进先出结构)。<
- 一组局部变量,其中每个变量都有一个索引(从零开始)。
根据 JVM 实现,它们在内存中可能连续也可能不连续。从逻辑上讲,它们是堆栈框架的两个独立部分。
如 description of aconst_null
中所述, aconst_null
指令推送 null
对象引用到操作数栈。
如 description of astore_<n>
中所述(其中 n
可以是 0、1、2 或 3):
The
<n>
must be an index into the local variable array of the current frame (§2.6). Theobjectref
on the top of the operand stack must be of typereturnAddress
or of typereference
. It is popped from the operand stack, and the value of the local variable at<n>
is set toobjectref
.
因此在您的示例中,语句 Object foo = null
翻译成以下内容:
- 推送
null
(指向“无”的特殊引用)放到操作数堆栈的顶部。
operand stack __________ | null | <-- null is pushed on the operand stack |__________| | | |__________| | | |__________|
- 从操作数堆栈中弹出引用并将其存储在索引为 1 的局部变量中。该局部变量对应于
foo
。 .
operand stack local variables __________ _______________ _______________ _______________ _______________ | | | args | foo (null) | | | |__________| |_______0_______|_______1_______|_______2_______|_______3_______| | | store null in LV#1 |__________| | | |__________|
对 Object bar = null
执行相同的步骤除了null
存储在索引 2 处的局部变量中。
来源:Java 虚拟机规范(参见 this section)。
关于java - Pushing variables to Stack 和 Variables living in the Stack 的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29946187/