作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图了解Java堆栈和堆内存。通过不同来源的阅读,我得出以下结论:
在本地(方法的一部分)声明的基本类型,例如int,
字节,字符等存储在堆栈中。
静态和实例(对象实例或类的一部分)原始类型存储在堆中。
简而言之,局部变量存储在堆栈中,而实例变量和静态变量存储在堆中。
本地引用的对象将在堆中创建,但是变量将在堆栈中创建。
实例/静态引用的对象将在堆中同时创建变量和对象。
(例如,本地car ferrari = new car()
将在堆栈中为ferrari
创建内存,而实际对象将在堆中。
堆栈变量ferrari
将具有实际对象堆位置的引用地址。
但是在进一步阅读时,我读到了堆栈中的内存分配给了前一帧的顶部。这让我对以下情况感到困惑:
问题1:
让我的方法是:
calculate(){
int a=15;
int b=25;
return a+b;
}
calculate(){
int a=15;
int b=25;
int z= a+b;
int y=a+b;
return y;
}
最佳答案
每个线程都有自己的堆栈。
每当线程调用方法时,都会在堆栈存储器中为该方法创建一个新块,以保存本地原始值并引用该方法中的其他对象。该存储块称为堆栈帧。方法结束后,该块将立即变为未使用状态,并将其从堆栈顶部移除。这是因为堆栈存储器始终按LIFO(后进先出)的顺序进行引用。
因此,如果您有代码:
void go(){
int x = 1;
foo(x);
}
void foo(int y){
int z = y;
bar();
}
void bar(){
Hello h = new Hello();
}
h
处于范围内。但是在完成
bar()
方法之后,
y
和
z
这两个变量都将在范围内。
0
上将是
this
引用,该引用指向堆上的对象。如果method是
static
,则位置
0
上的将是该方法的第一个参数。局部变量数组的大小在编译时确定。要查看局部变量数组,您需要查看已编译的Java代码。对于第一个
calculate()
方法(如果是
static
),局部变量数组将如下所示:
Name
列)与其在数组中的位置(
Slot
列)之间的关系。
a
之前的
b
值用于操作
a + b
?
b
)。现在,值
a
在操作数堆栈的顶部。同时弹出(读取和删除)此值(操作数堆栈现在为空),并将这两个值相加。将结果放回操作数堆栈。现在,操作数堆栈仅包含结果。
calculate()
时,将创建新的堆栈框架并将其放在堆栈顶部。语句
int a = 15;
在内部分为2个步骤:
15
放在操作数堆栈的顶部,
15
),并将其保存在特定索引的局部变量数组中。
int b = 25;
重复相同的步骤。现在,您有2个值保存在局部变量数组和空操作数堆栈中。最后的
return a + b;
分4个步骤完成:
a
从局部变量数组推送(加载)到操作数堆栈,
b
从局部变量数组推入(加载)到操作数堆栈。现在,操作数堆栈上有两个值。
b
值)。从操作数堆栈中弹出第二个值(这是
a
值)。此时,操作数堆栈为空。将这两个值相加并将结果推回操作数堆栈。现在操作数堆栈仅包含加法运算的结果。
a
和
b
来计算
z
,变量
y
如何能够再次访问
a
和
b
,因为已经从堆栈中使用了它?
int a = 15
和
int b = 25
以与Q1中相同的方式进行。
int z = a + b;
是这样执行的:
a
从局部变量数组推送(加载)到操作数堆栈,
b
从局部变量数组推入(加载)到操作数堆栈。现在,操作数堆栈上有两个值。
b
值)。从操作数堆栈中弹出第二个值(这是
a
值)。此时,操作数堆栈为空。将这两个值相加并将结果放在操作数堆栈上。现在操作数堆栈仅包含加法运算的结果。
a + b
结果),并将其保存在特定索引的局部变量数组中。
int y = a + b;
的执行方式与
int z = a + b;
相同。
return y
:
y
值从局部变量数组推入操作数堆栈,
关于java - 如何在Java中访问堆栈内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57336595/
我是一名优秀的程序员,十分优秀!