8

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

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

谢谢。

4

4 回答 4

9

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

不,它取决于它是原语还是参考。这取决于使用堆栈还是堆的范围。局部变量在栈上分配,成员变量在对象实例化时在堆上分配。

另请参阅Java 原语是在堆栈上还是在堆上?

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

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

考虑以下代码片段:

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

  i = i + 5;
  return result;
}

在这里,在堆栈上创建了一个基元 ( int i),并对其进行了一些计算。一旦方法完成,i就不能再访问,它的值就丢失了。引用基本上也是如此result:引用是在栈上分配的,而 Object(在这种情况下是 String 对象)是在堆上分配的。通过将引用作为返回值返回,它所引用的对象仍然可以在方法之外使用。

于 2012-12-17T11:23:14.033 回答
6

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

HotSpot JVM 可以执行逃逸分析,如果它确定一个对象不可能逃逸方法范围,它实际上会在堆栈上分配它。

于 2012-12-17T11:27:19.040 回答
1

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

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

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

例如: -

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

在上述情况下,str引用将在 上分配内存stack,当然如果它是在某个本地范围内定义的。并且它将指向在 上创建的新字符串对象Heap

于 2012-12-17T11:24:33.080 回答
0

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

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

stack从概念上讲,理想情况下,如果数据不在其之上,则无法从中检索任何数据。但在现实世界中,您需要从程序中的任何位置访问某个位置。所以,不能叠加。他们给它起了名字heap

这个链接可能会更清楚地说明它。

于 2012-12-17T11:23:59.977 回答