日期:2014-05-20  浏览次数:20726 次

引用真的都非配在栈内存中吗?
Java code

public class People {
    private String name;
    private int age;
    private Info info;
    
    public static void main() {
        People p = new People(); //当运行完这句的时候内存的分配情况
    }
}
class Info {
    
}



自己画的图,非常不标准。





谁能给我解释下。

今天突然想到的。




------解决方案--------------------
哪个线程中p.info的地址都一样,所以可以存在栈中的。

------解决方案--------------------
栈中只有一个p的引用,应该不是1楼的情况。

你想,如果你那个Info类不是一个简单的类,而还有数据元素,如下面这种情况:
class Info{
String s = new String();
Info i = new Info();
}

那p.info.s和p.info.i又放哪里呢,

或者p.info.i.i.i.i.i...这种情况又如何考虑?
------解决方案--------------------
楼主发的帖子图是正确的。

很多人所谓“引用分配在栈中”是这样说的“引用分配在栈中,对象分配在堆中”,p.Info是对象的一部分,自然是在堆中。

注意表达环境。


------解决方案--------------------
不是吧。。 容器啊lz,容器中存的都是引用啊 容器是在堆中吧?那容器中的引用也就在堆中喽~~
------解决方案--------------------
楼主,我认为你顶帖里面说的是对的,引用别处的一句话:

堆中存的是对象,栈中存的是基本数据类型和堆中对象的引用。一个对象的大小是不可估计的,或者说是可以动态变化的,但是在栈中,一个对象只对应了一个4btye的引用(堆栈分离的好处)

这里的解释我认为比较清楚,可参见:
http://developer.51cto.com/art/200911/165015.htm


至于你说“对,那如果有人说,引用都分配在栈中就错了呗?”这句话完全要看这句话的背景,因为一般人都是将线程作为背景在讨论的,如果你把线程这个范围界定进来,那我认为这句话就没啥错误;而一个对象中包含另一个对象,显然不在这之列。
------解决方案--------------------
也就是说,只要是线程所直接申请的引用,都是分配在栈中的。对象内对另一个对象的引用,则是跟着对象走的,与线程直接申请的引用不相干。
------解决方案--------------------
首先,要理解,堆和栈,两种数据结构的特点。
堆,对于局部内存的分配管理非常方便。
栈,可以记录先前压入元素的信息。
所以,一般情况下,
堆,用于保存数据;栈,用于压入函数调用时的“现场环境”。
听说过,函数调用,需要“现场保护”吧?

所以说,栈,保存的引用,是当前上下文环境中的对象引用。

我们编写的程序,可以换个角度来理解,无非就是指令和数据,
也就是通常所说的 函数 和 数据,
函数通过线程调用来操纵数据,完成业务功能。
那么,当程序执行到某个函数时,函数能访问的数据对象,构成了当前的上下文环境,
而这些环境中的对象,其引用,通常会被压入栈中,便于调用其他函数时的现场保护。

以上均属个人理解,如有不同理解,请互相交流。
谢谢。


------解决方案--------------------
堆和栈,都是运行时的数据结构。
不能静态的去理解。
我不是说了吗 ? 栈里保存的是当前的上下文环境,
你的函数,当前访问某个对象的引用,那么,栈里就有哪个对象的引用,不访问,就没有。

当你的函数,即访问了p对象,又访问了p.info对象,那么,栈里就有两个引用。

但是,p对象内部的info变量,始终指向对应的Info对象,而不是栈。

------解决方案--------------------
探讨

引用:

栈中只有一个p的引用,应该不是1楼的情况。

你想,如果你那个Info类不是一个简单的类,而还有数据元素,如下面这种情况:
class Info{
String s = new String();
Info i = new Info();
}

那p.info.s和p.info.i又放哪里呢,

或者p.info.i.i.i.i.i.……