我确实知道在 Java 中(也可能在 .net 中),原语存储在堆栈中,而引用类型存储在堆中。
我的问题是我不了解这种行为的过程/缺点。为什么我们不能引用堆栈内的内存位置呢?. 我在谷歌上搜索时找不到合适的解释(也许我很烂),但如果你们能提供一些见解,我将不胜感激
谢谢。
我确实知道在 Java 中(也可能在 .net 中),原语存储在堆栈中,而引用类型存储在堆中。
我的问题是我不了解这种行为的过程/缺点。为什么我们不能引用堆栈内的内存位置呢?. 我在谷歌上搜索时找不到合适的解释(也许我很烂),但如果你们能提供一些见解,我将不胜感激
谢谢。
我确实知道在 Java 中(也可能在 .net 中),原语存储在堆栈中,而引用类型存储在堆中。
不,它不取决于它是原语还是参考。这取决于使用堆栈还是堆的范围。局部变量在栈上分配,成员变量在对象实例化时在堆上分配。
我的问题是我不了解这种行为的过程/缺点。
只要您的方法正在执行,存储在堆栈中的数据就会一直存在。一旦方法完成,堆栈上分配的所有数据都将被删除。存储在堆上的数据只要不被丢弃(在 Java 的情况下,由垃圾收集器在后台完成)就可以存活。在 C/C++ 等其他语言中,您明确需要删除/释放在堆上分配的数据。
考虑以下代码片段:
String someMethod() {
int i = 0;
String result = "Hello";
i = i + 5;
return result;
}
在这里,在堆栈上创建了一个基元 ( int i
),并对其进行了一些计算。一旦方法完成,i
就不能再访问,它的值就丢失了。引用基本上也是如此result
:引用是在栈上分配的,而 Object(在这种情况下是 String 对象)是在堆上分配的。通过将引用作为返回值返回,它所引用的对象仍然可以在方法之外使用。
您通常不能将引用类型存储在堆栈上,因为堆栈框架在方法返回时被破坏。如果您保存了对对象的引用,以便在方法完成后可以取消引用,那么您将取消引用不存在的堆栈位置。
HotSpot JVM 可以执行逃逸分析,如果它确定一个对象不可能逃逸方法范围,它实际上会在堆栈上分配它。
其中引用类型存储在堆上。
我不知道那部分到底是什么意思,但请记住,只有对象存储在 上heap
,而指向这些对象的引用仍在堆栈上。可能这就是你的疑问。
现在,您还应该注意,只有局部变量存储在 上stack
,而instance / member
变量存储在Heap
.
例如: -
String str = new String("Rohit"); // Local variable
在上述情况下,str
引用将在 上分配内存stack
,当然如果它是在某个本地范围内定义的。并且它将指向在 上创建的新字符串对象Heap
。
为什么我们不能引用堆栈内的内存位置呢?
您可以将此决定视为内存架构决定。
stack
从概念上讲,理想情况下,如果数据不在其之上,则无法从中检索任何数据。但在现实世界中,您需要从程序中的任何位置访问某个位置。所以,不能叠加。他们给它起了名字heap
。
这个链接可能会更清楚地说明它。