Java堆和堆栈
我想再次学习Java,因为我几年前就离开了它。 读一本书我有一个问题,就是理解Java如何在堆栈和堆栈中分配内存。
这就是我所理解的 - 我会试着用例子来谈论它。
class TestA {
int a;
void methodA(int b) {
a = b;
}
int getA() {
return a;
}
}
这是一个示例类,以显示不同的情况。 这是我的主要:
int b = 3;
TestA obj = new TestA();
obj.methodA(b);
obj.getA();
那么会发生什么?
## 开始
STACK - 为主要功能提供一些内存
HEAP - 空
## int b = 3
STACK - [为主要功能提供一些内存 - >在这里我们有b]
HEAP - [空]
## TestA obj = new TestA()
STACK - [为主要功能提供一些内存 - >这里我们有b和对TestA的引用]
HEAP - [为int a留出一些记忆]
## obj.methodA(b);
STACK - [为主要功能提供一些内存 - >这里我们有b和对TestA的引用]
HEAP - [为int a带来一些内存]和[methodA的另一个内存]
##执行方法A(int b)
STACK - [为主函数获取一些内存 - >这里我们有b和一个对TestA的引用] AND [为methodA() - >获取内存我们在这个函数中使用了b]
HEAP - [为int a带来一些内存]和[methodA的另一个内存]
我们有:
这样对吗?
首先,请记住这个堆还会为您的类(以及其他几个类)提供Class
实例。
回覆:
## TestA obj = new TestA()
STACK - [为主要功能提供一些内存 - >这里我们有b和对TestA的引用]
HEAP - [为int a留出一些记忆]
a
将作为为TestA
实例分配的内存的一部分存放在堆中,而不是堆栈中。 b
和obj
在堆栈上,在进入main
时进行分配(呃,我认为这是发生的时间;可能是JVM不会为它们保留堆栈空间,直到它遇到程序流程中的声明,但是在那里我们正在进入JVM的内部)。 该堆还包含TestA
的实例。 (请记住,变量obj
与它指向[ TestA
的实例]的内容TestA
;这些东西中的每一个都需要内存。)
还要记住堆栈将包含函数调用的返回地址。 例如,当main
调用methodA
,当methodA
返回时JVM应该返回的地址也在堆栈上。
各种堆栈结构也将被分配用于异常处理。
以上主要是理论上的,头脑。 欢迎JVM进行优化,并且它们(HotSpot是彻底优化的JVM)。 例如,@Voo指出,如果JVM可以检测到它们可以将对象放入堆栈,那么它就可以(例如,只在方法中使用对象实例,而JVM的字节码分析表明它不可能存在当该方法退出时,成为它的一个优秀参考)。
虽然Java被指定为堆栈机器,但实际上并没有以这种方式实际执行,所以在实际的JVM中,堆栈的大小只会在退出或进入方法时发生变化。
堆永远不会是空的 - 它包含Object.class
等对象,在main
启动之前由引导类加载器实例化。
像new ClassName(...)
这样的所有操作都会在堆中分配空间*,并且所有变量声明( int x
, Object ref
)指定在输入封闭函数时应该在堆栈上留出空间**。
* - 请参阅https://stackoverflow.com/a/8690592/20394上有关优化的警告
** - 再次优化会导致共享堆栈插槽。
默认情况下,所有对象都分配在堆上。 但是,有编译器优化允许在堆栈上分配对象(或避免一起分配)。 特别是逃逸分析允许在Java 6中这一点。
链接地址: http://www.djcxy.com/p/255.html上一篇: Java heap & stack