我确实知道在Java中,(也许在.net中),原语存储在堆栈上,其中引用类型存储在堆上。
我的问题是,我不理解这种行为的过程/缺点。为什么我们不能在堆栈中引用内存位置呢? 。我用谷歌搜索时找不到合适的解释(也许我很糟糕),但如果你能提供一些见解,我将不胜感激
感谢。
答案 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可能会给它带来更多启示。