Kor*_*gay 13 java stack jvm memory-management bytecode
所以我知道存在2个内存区域:Stack和Heap.
我也知道如果你创建一个局部变量,它将存在于堆栈中,而不是堆中.随着我们将数据推入其中,堆栈将会增长,如:

现在我将尝试通过我对你的困惑:
例如,这个简单的Java代码:
public class TestClass {
public static void main(String[] args) {
Object foo = null;
Object bar = null;
}
}
Run Code Online (Sandbox Code Playgroud)
被翻译成这个字节码:
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;
Run Code Online (Sandbox Code Playgroud)
根据定义,acons_null是:
push a null reference onto the stack
Run Code Online (Sandbox Code Playgroud)
而astore_1是:
store a reference into local variable 1
Run Code Online (Sandbox Code Playgroud)
我遇到的困惑是,我们将foo推入堆栈,然后我们将它再次存储在堆栈中?将引用存储在局部变量中意味着什么?该局部变量在哪里生活?同样的堆栈我们将foo推入或者是这些单独的堆栈?
现在,如果我在第一个对象上调用一个方法,我将其推入堆栈,因为堆栈指针指向我推送的最后一个元素,它将如何处理?
man*_*uti 13
JVM中每个线程都有一个堆栈.每个堆栈由几个框架组成:每个方法调用都会创建一个新框架,并且在完成方法调用时,框架将被销毁.
在堆栈框架内有两个区域:
根据JVM实现,它们在内存中可能是连续的,也可能不是连续的.从逻辑上讲,它们是堆栈框架的两个独立部分.
如在描述中aconst_null所解释的,该aconst_null指令将null对象引用推送到操作数堆栈上.
并且如在(其中可能是0,1,2或3)的描述中astore_<n>所解释的n:
的
<n>必须是一个指数到当前帧(§2.6)的本地变量数组.在objectref操作数堆栈的顶部的类型必须是returnAddress或类型的reference.它从操作数堆栈中弹出,并将局部变量at的<n>值设置为objectref.
因此,在您的示例中,该语句Object foo = null转换为以下内容:
null(指向"无"的特殊引用)推到操作数堆栈的顶部.Run Code Online (Sandbox Code Playgroud)operand stack __________ | null | <-- null is pushed on the operand stack |__________| | | |__________| | | |__________|
foo.Run Code Online (Sandbox Code Playgroud)operand stack local variables __________ _______________ _______________ _______________ _______________ | | | args | foo (null) | | | |__________| |_______0_______|_______1_______|_______2_______|_______3_______| | | store null in LV#1 |__________| | | |__________|
Object bar = null除了null存储在索引2的局部变量中之外,执行相同的步骤.
来源:Java虚拟机规范(参见本节).
| 归档时间: |
|
| 查看次数: |
1507 次 |
| 最近记录: |