困惑于Java内存管理(堆栈和堆)

时间:2012-05-17 03:39:53

标签: java memory-management callstack

这可能听起来很愚蠢,但我仍然不清楚Java Stack和内存堆。我从学习中得知的是:

1)所有方法调用都在堆栈上进行。

2)本地分配的所有内存都在内存堆上(关于这一点不太清楚)

3)新运算符(在方法或类中)分配的所有内存都在内存堆上。

我担心以下情况:

1)如果我在一个方法中创建一个int变量并返回它,它会去哪里(我相信它会进入堆栈,但需要澄清)。

2)如果我在方法中创建一个新对象,即使在方法执行结束后,它也会存在于堆内存中(我明白这是因为当我分配这个时,java创建的对象的哈希码仍然相同)对某些外部引用变量或我返回此对象)。

3)我的问题是如果我没有将第2点中提到的对象分配给任何引用或者我没有返回它,会发生什么。它仍然是在堆上创建的吗?逻辑上应该是但请赐教。

2 个答案:

答案 0 :(得分:8)

所有方法参数都在堆栈中。所有局部变量都在堆栈上。堆中唯一的东西是使用new显式分配的东西(或者通过自动装箱或varargs隐式分配。)

考虑它的另一种方法是原始值和对象/数组引用可以在堆栈上,但实际对象不能 1

所以:

1) - 你正在返回一个原始值(不是一个变量!),它会进入堆栈。 (你不能“返回”一个变量。变量是堆栈框架的一部分,不能与它分离。)

2)是的。

3)是的,至少现在 1 。在某些时候,GC可能会运行,注意应用程序不再引用该对象,并回收它。


1 - 实际上,最新的Hotspot编译器能够检测到对象的引用永远不会从创建它的方法中“逃逸”,并且可以在堆栈上分配对象。 IIRC,需要使用JVM命令行标志启用此优化 - 称为转义分析。

答案 1 :(得分:1)

代码段:常量值通常直接放在程序代码段中。

Stack:对象引用和原始变量放在堆栈上。

堆:无论何时创建对象,都会在执行该代码时在堆上分配存储。

对于你的问题:

1)是

2)是的

3)是的