为什么引用类型存储在堆中

时间:2012-12-17 11:18:19

标签: java jvm heap

我确实知道在Java中,(也许在.net中),原语存储在堆栈上,其中引用类型存储在堆上。

我的问题是,我不理解这种行为的过程/缺点。为什么我们不能在堆栈中引用内存位置呢? 。我用谷歌搜索时找不到合适的解释(也许我很糟糕),但如果你能提供一些见解,我将不胜感激

感谢。

4 个答案:

答案 0 :(得分:9)

  

我确实知道在Java中,(也许在.net中),原语存储在堆栈中,其中引用类型存储在堆上。

没有。 取决于它是基元还是引用。它取决于范围是否使用堆栈或堆。局部变量在堆栈上分配,成员变量在实例化对象时在堆上分配。

另见Do Java primitives go on the Stack or the Heap?

  

我的问题是,我不理解这种行为的过程/缺点。

只要您的方法正在执行,存储在堆栈中的数据就会存在。方法完成后,将删除堆栈上分配的所有数据。 存储在堆上的数据只要不被丢弃就会存在(在Java的情况下,由垃圾收集器在后台完成)。在其他语言中,如C / C ++,您明确需要删除/释放在堆上分配的数据。

请考虑以下代码段:

String someMethod() {
  int i = 0;
  String result = "Hello";

  i = i + 5;
  return result;
}

这里,在堆栈上创建了一个原语(int i),并对其进行了一些计算。方法完成后,无法再访问i,其值将丢失。对result引用基本相同:引用在堆栈上分配,但Object(在本例中为String对象)在Heap上分配。通过将引用作为返回值返回,它引用的对象仍然可以在方法之外使用。

答案 1 :(得分:2)

通常不能在堆栈上存储引用类型,因为在返回方法时会破坏堆栈帧。如果您保存了对象的引用,以便在方法完成后可以取消引用它,那么您将取消引用不存在的堆栈位置。

HotSpot JVM可以执行转义分析,如果它确定某个对象不可能转义方法范围,它实际上会将它分配到堆栈上。

答案 2 :(得分:1)

  

其中引用类型存储在堆上。

我不知道那个部分究竟是什么意思,但请记住,只有对象存储在heap上,而指向这些对象的引用仍然在堆栈中。可能这是你的怀疑。

现在,您还应注意,只有局部变量存储在stack上,而instance / member变量存储在Heap上。

例如: -

String str = new String("Rohit");  // Local variable

在上面的情况下,str引用将在stack上分配内存,如果它在某些本地范围内定义的话。它将指向在Heap上创建的新字符串对象。

答案 3 :(得分:0)

  

为什么我们不能在堆栈中引用内存位置呢?

您可以将此决定视为内存架构决策。

理想情况下,如果不是stack,则无法从heap检索任何数据。但在现实世界中,您需要从程序中的任何位置访问某些位置。所以,它不能堆叠。他们将其命名为{{1}}。

link可能会给它带来更多启示。