Given the following,
1.class X2{
2.         public X2 x;
3.         public static void main(String[] args){
4.         X2 x2=new X2();
5.         X2 x3=new X2();
6.         x2.x=x3;
7.         x3.x=x2;
8.         x2=new X2();
9.         x3=x2;
10.         doComplexStuff();
11.}
12.}
after line 9 runs,how many objects are eligible for garbage collection?
A.0  B.1  C.2  D.3  E.4请概念清楚者给出详细的解释,谢谢~~~

解决方案 »

  1.   

    8.         x2=new X2();
    9.         x3=x2;
    这时只有第8行的这个new X2对象被引用,所以不被回收,其余的第4,5 行的对象new X2()没有被引用所以被垃圾回收,所以我认为是2个。
      

  2.   

    java里并不是以ref的判断来决定gc的
      

  3.   

    我觉得是2。到第9行时,   
    4. X2 x2=new X2();
    5. X2 x3=new X2();
    可以回收,而9.  x3=x2;则是
    x3、x2共同指向8.x2=new X2();创建的对象。所以是2。
      

  4.   

    本来是跟在gemouzhi(gemouzhi) 后面的,中间有人发言了。
    晕。
      

  5.   

    根据不同的JVM的GC机制,答案应该不确定,0和2都有可能.
    根据ref来判断回收的话,前两个X2对象是相互引用的,答案是0.
    但这样肯定是会造成内存泄漏的,所以现实中JVM都应该采用孤岛回收的策略.2,认同.
      

  6.   

    public class GcTest {
        public GcTest g;
        public static void main(String[] args) {
            GcTest x2 = new GcTest();
            GcTest x3 = new GcTest();
            x2.g = x3;
            x3.g = x2;
            x2 = new GcTest();
            x3=x2;
            System.gc();
        }
        @Override
        protected void finalize() throws Throwable {
            System.out.println("clear");
        }}测试了一下,输出2次clear
      

  7.   

    之所以感觉是因为,我觉的:最后那个对象的ref在网络stack上并不存活。你是没感觉不是感觉不出来。yqj2065(严千钧) 你贴一段你测试的代码我看看
      

  8.   

    谢谢楼上的代码,结合TIJ的148-154,终于搞明白了一些,我还做了其他测试。很cool谢谢simbas00
      

  9.   

    To gemouzhi:没感觉、感觉不出来?不要这样说。
    既然有2个人说3,就想听听为什么。测试的代码,上面 simbas00给了。To sussman:我的详细的解释。
    这个题糊弄人的地方,在
    2.         public X2 x;
    因此,要清楚引用变量(或者叫句柄)和对象是不同的两个东西。句柄将持有对象的ref,它不是对象。有几个句柄?4个,x2、x3、x2.x和x3.x,程序中有几个对象?数new出现的次数(Class的那个方法这里不考虑)。3个。垃圾对象是引用全部失效的对象,
    6.         x2.x=x3;
    7.         x3.x=x2;
    说明,对象1#和2#的引用曾经被x3.x和x2.x持有,当8.         x2=new X2();
    9.         x3=x2;
    8后,x2.x为null,9之后,x3.x为null。因此
    对象1#和2#成为垃圾。
    而对象3#有句柄x2和x3持有。
      

  10.   

    8后,x2.x为null
    -----
    我不这样认为,8后,x2.x不为null
      

  11.   

    sorry,我可能理解的有问题,我再看一下
      

  12.   

    8后,x2指向的对象是新对象啊,其成员变量x仅仅被默认初始化,当然是null了。
      

  13.   

    yqj2065(严千钧) 你解释一下8后,x2.x为null,谢谢
      

  14.   

    我是想说:1,x2其成员变量x你认为在什么地方分配内存?2,这个成员变量x为什么会在x2指向新对象的时候她指向null?因为这个对象原来是有所指的。
      

  15.   

    x2其成员变量x的内存分配,一定在heap中,而x2本身则在stack中。成员变量x为什么会在x2指向新对象的时候她指向null?
    晕,上面说了啊。
    “x2指向的对象是新对象啊,其成员变量x仅仅被默认初始化,当然是null了”
      

  16.   

    x2其成员变量x的内存分配,一定在heap中。恩,我到希望是这样,因为这样更好叫我理解,但对象的成员变量分配在heap上,你有根据吗?有的话,给你加100分。x2指向的对象是新对象,但是这个时候并没有进行gc,所以x2原来指向的堆上的对象还是存活的而且我按simbas00给的代码打出x2.x都是@9664a1。这些都是小问题。对象的成员变量分配在heap上,我还真没弄明白,你先找些根据。这个GcTest 也是对象吧GcTest x2是她的成员吧,你的意思是x2也分配在heap上?public class GcTest {
        public GcTest g;
        public static void main(String[] args) {
            GcTest x2 = new GcTest();
            GcTest x3 = new GcTest();
            x2.g = x3;
            x3.g = x2;
      

  17.   

    呵呵,朋友,
    对象的成员变量分配在heap上,你有根据吗?
    这是Java内存管理最基本的规定。对象的内存在heap分配,就是说的是对象的所有成员变量在heap分配空间啊。x2也分配在heap上?
    no,局部变量全部在stack中分配空间。
      

  18.   

    “这个GcTest 也是对象吧GcTest x2是她的成员吧,你的意思是x2也分配在heap上?public class GcTest {
        public GcTest g;
        public static void main(String[] args) {
            GcTest x2 = new GcTest();
            GcTest x3 = new GcTest();
            x2.g = x3;
            x3.g = x2;

    public GcTest g;
    g是成员,x2不是,
      

  19.   

    分是小问题,关键我要搞懂,嘎嘎,等我把这篇文章看完。不就是分嘛,没问题。我先看一下,局部变量和对象的成员变量的内存分配。对了。关于simbas00给的代码打出x2.x的地址的问题,也希望你能指教一下
      

  20.   

    你的代码可能有问题。
    public class A {
        public A g;
        public static void main(String[] args) {
            A x2 = new A();
    System.out.println(x2.g);        A x3 = new A();
            x2.g = x3;System.out.println(x2.g);
            x3.g = x2;
            x2 = new A();System.out.println(x2.g);
            x3=x2;
            System.gc();
        }
        @Override
        protected void finalize() throws Throwable {
            System.out.println("clear");
        }}null
    A@11b86e7
    null
    clear
    clear
      

  21.   

    等我找找不同,just waitpublic class GcTest {
        public GcTest g;
        public static void main(String[] args) {GcTest x2 = new GcTest();
    GcTest x3 = new GcTest();
    x2.g = x3;
    System.out.println(x2);x3.g = x2;
    x2 = new GcTest();
    x3=x2;
    System.gc();
    System.out.println(x2);      }
        protected void finalize() throws Throwable {
            System.out.println("clear");
        }}
      

  22.   

    太cool了,代码我已OK了,还有,如果是这样全分配在堆上,java关于子对象访问父对象的变量那是不是太强了,所以我一直不以为分配在堆上,当然,现在我在没找到官方资料之前无法说什么,但是,嘎嘎,5分钟后等着领分,然后我来回答楼主的问题。
      

  23.   

    1.class X2{
    2.         public X2 x;//这个是X2的成员变量,内存组织描述在field_info里,
    3.         public static void main(String[] args){//主方法
    4.         X2 x2=new X2();//x2是X2的局部变量,分配在栈上,只是一个ref,他指向一个在heap上分配的内存new X2();,这个好象是16K,这个new X2();中的x的成员变量是和这个对象的生命周期是一样的.因为我还再查关于成员变量堆内存的组织形式.
    5.         X2 x3=new X2();//x3同x2
    6.         x2.x=x3;//这里用x2的x成员变量指向了x3也同时指向的 在heap上分配的new X2();
    7.         x3.x=x2;//这里用x3的x成员变量指向了x2也同时指向的 在heap上分配的new X2();
    8.         x2=new X2();//这里x2在栈中新指向了另一个new X2();而原来的她所指向的那个对象只有x3的x作为她的ref,到这里我认为还没有任何的垃圾.
    9.         x3=x2;//这步才是产生垃圾最重要的那部分,因为x3指向了新的对象,也就是说没有任何栈上的指针指向最初分配的那两个对象了.就相当于两个内存的heap上的内存块互相指着.
    而这种没有栈指针依赖的对象是无法存活的.
    例如你直接写这样的代码:new X2();就会利马变成垃圾.
    所以在这一步同时出现了两个垃圾对象,也就是最初的两个new X2();
    10.
    11.}
    12.}
    结论: 答案是两个我希望你能楼主和大家,当然还有yqj2065(严千钧)看一下,第8行,因为我认为这里并不产生垃圾这是我对这个帖子的半完整解释.遗留的问题:成员变量在heap上的组织形式.谢谢各位观看.
      

  24.   

    我倒觉得是0,因为第9行之后还有一个对doComplexStuff()的调用
    再说是不是应该出了"}"外,垃圾回收机制才会生效呢?我觉得关键是要弄清楚垃圾回收机制是在什么时候被调用的?
    上面的各位都是在自己的代码中强制调用System.gc()才的得到结论。
      

  25.   

    提高...
    欢迎有JAVA#JSP兴趣的加入技术群:15328132
    (为了不让无关人员加入,请回答一个JAVA的简单问题久可以接受高手们的指点!)
      

  26.   

    这道题似乎没有那么复杂,支持选 C 回收了 2 个,试解释如下:Given the following,
    1.class X2{
    2.         public X2 x;
    3.         public static void main(String[] args){
    4.         X2 x2=new X2();
    5.         X2 x3=new X2();
    6.         x2.x=x3;
    7.         x3.x=x2;
    8.         x2=new X2();
    9.         x3=x2;
    10.         doComplexStuff();
    11.}
    12.}
    after line 9 runs,how many objects are eligible for garbage collection?
    A.0  B.1  C.2  D.3  E.4--
    运行到line 5时,共创建了 2 个实例,并且交叉赋值给 x2, x2.x, x3, x3.x
    这没有什么特别的,概括地讲也就是说:
        x2,x3分别持有一个实例,同时根据成员变量x可以访问另外一个。--
    运行到line 8时,情况发生了变化,x2指向一个新的实例(x2.x自然而然也就null了)
    此时
        x2持有第 3 个实例,但 x2.x = null (并不指向任何实例)
        由于 x3 及 x3.x 仍然持有前面创建的 2 个实例,所以目前还没有对象被释放。--
    运行到line 9时,x3也指向新的实例(和x2引用同一个实例)
    此时
        x3原来持有的实例被释放
        能够通过 x3.x 访问的实例也被释放--
    用符号ABC表示实例就是从x2 -> A
    x2.x -> B
    x3 -> B
    x3.x -> A最终演变为x2 -> C
    x2.x is null
    x3 -> C
    x3.x is null至此 A 和 B 将被 gc
      

  27.   

    答案是2个,没问题。但是使用finalize的测试是不对的。
    上面大家分析的已经很不错了,我只是想说说上面的finalize的测试方法为什么是错误的?!我们知道gc是个不确定的行为,我们无法控制,JVM回收垃圾一直都是不可控的。
    我认为这个题目出的比较好,如果这个代码
    public class GcTest {
        public GcTest g;
        public static void main(String[] args) {
            GcTest x2 = new GcTest();
            GcTest x3 = new GcTest();
            x2.g = x3;
            x3.g = x2;
            x2 = new GcTest();
            x3=x2;
            System.gc();
        }
        @Override
        protected void finalize() throws Throwable {
            System.out.println("clear");
        }}
    输出多少次clear我觉得都是没有问题的,(当然不会超过3次,因为一共就创建了3个对象)。这个代码和题目是不一样的。
    题目中line9之后还有line10,这个是非常重要的,也就是说line9之后这个方法的作用域还没有结束,这时候符合垃圾回收的对象应该是
    1。null
    2。没有被引用的对象
    而line10之后,就会有“结束作用域的局部对象”也符合垃圾回收的条件。
    上面的finalize的测试就是犯了这个错误,实际上你这里按照题目的问题应该是3个对象,因为按照上面3条原则,创建的3个对象都是局部的,所以结束了函数作用域一定都符合垃圾回收的条件。之所有只输出了2次clear是因为gc是不确定的,这里gc了2个对象而已,但是符合垃圾回收的对象是3个!
      

  28.   

    The JVM is divided into four conceptual data spaces:Class area, where the code and constants are keptJava stack, which keeps track of which methods have been called and the data associated with each method invocationHeap, where objects are keptNative method stacks, for supporting native methods
      

  29.   

    An object is ready to be garbage collected when it is no longer "alive." The rules for determining if an object is alive follow.If there's a reference to the object on the stack, then it's alive.If there's a reference to the object in a local variable, on the stack, or in a static field, then it's alive.If a field of an alive object contains a reference to the object, then it's alive.The JVM may internally keep references to certain objects, for example, to support native methods. These objects are alive.
      

  30.   

    jFresH_MaN的解释,
    正确与错误的解释。“finalize测试是不对的”“gc是个不确定的行为,我们无法控制,JVM回收垃圾一直都是不可控的”,理论上是正确。使用finalize的测试方法 ,常常忽略了“可回收”与“被回收”的差别。“题目中line9之后还有line10,这个是非常重要的,也就是说line9之后这个方法的作用域还没有结束”,
    “而line10之后,就会有“结束作用域的局部对象”也符合垃圾回收的条件。”
    “创建的3个对象都是局部的”
    错误的或者说混乱的解释。一个基本的观点:对象没有/不受词法作用域的限制,受词法作用域限制的是引用变量(或者叫句柄)。作用域结束后,句柄被清除,可能由于对象ref的最后一个持有者丧失而导致对象沦为垃圾。
    不要混淆对象与句柄。
    如果能够让对象方便的受词法作用域限制,Java中的对象就不需要在heap中分配内存了。按照题目的问题,9后,垃圾对象是两个,当然此时使用finalize测试也是两个。
      

  31.   

    顺便说一下:对象的成员变量的内存分配全部在heap中,正如
    liu_you(滴水藏海) 摘录的"Heap, where objects are kept"但是,不同的JVM如何实现是另外一回事.有文章介绍,有的JVM甚至可以在物理的寄存器中给对象分配内存.我们仍然把这时的物理的寄存器视为heap.
      

  32.   

    heap和stack都是内存,但是使用了不同的组织形式,正如对象分配在heap上绝对不会是随便的扔进heap内存,而我所要找的,就是要把,堆内存分配的结构和组织形式找到因为这直接关系到,子对象对父对象成员变量的访问,而不是笼统的说一下分配在堆上,那和直接说分配在内存里没有区别了
      

  33.   

    To gemouzhi(gemouzhi) "第8行,我认为这里并不产生垃圾",正确!
      

  34.   

    Heap, where objects are kept等于没说,例如java的句柄池,方法区,操作数的栈,还有最重要的关于帧的分配
      

  35.   

    两个public class A {
        public A g;
        public static void main(String[] args) {
            A x2 = new A();
            A x3 = new A();
            x2.g = x3;
            x3.g = x2;
            x2 = new A();
            x3=x2;
            while(true)
            {
             System.gc();
            }
            
        }
        @Override
        protected void finalize() throws Throwable {
            System.out.println("clear");
        }}
      

  36.   

    To gemouzhi(gemouzhi) 
    "我所要找的,就是要把,堆内存分配的结构和组织形式找到"
    呵呵,有出息的家伙
      

  37.   

    http://community.csdn.net/Expert/topic/4411/4411549.xml?temp=.9349787
    希望 yqj2065(严千钧) 大哥能来这里踩一脚,我已没办法给分了
      

  38.   

    我是比较痴迷于MFC的vtable和VCL的VMT。java也是人做出来的,无论如何的高级,他都会留有上一代编译器的影子.java也是人做出来的,我个人认为有可能会有高级的内存泄漏.希望能和大家交流,因为我现在水平还不行,先看完,老外那本inside JVM也许会有启发.然后回来发贴分享一下.谢谢 yqj2065(严千钧) 大哥对我指教.
      

  39.   

    To gemouzhi(gemouzhi) :
    指教不敢,偶水平有限得很.
      

  40.   

    选c
    这题考的是java的垃圾回收、对象生成的机制
    这就要说到堆内存和栈内存
      

  41.   

    结果有x指向的对象和另一个是x2与x3指向相同的对象,共两个吧,你想弄清楚概念的话或者要看看java pratical
      

  42.   

    yeah you are the man!!up!!
      

  43.   

    1.class X2{
    2.         public X2 x;
    3.         public static void main(String[] args){
    4.         X2 x2=new X2();   //产生新对象放到堆中。对象A1
    5.         X2 x3=new X2();  //产生新对象放到堆中。对象A2
    6.         x2.x=x3;  //现在对象A2的句柄为:x2.x  ,x3  两个
    7.         x3.x=x2;  //现在对象A1的句柄为:x3.x ,x2   两个
    8.         x2=new X2();      //产生新对象放到堆中。对象A3 。句柄为  x2  同时对象A1丢失一个句柄x2  现在A1还有句柄x3.x
    9.         x3=x2;   //A2丢失句柄 x3   目前A2还有句柄 x2.x。到次为止每个对象都有句屏,不会被当做垃圾回收。
    10.         doComplexStuff();
    11.}
    12.}
      

  44.   

    At runtime, data is represented in two ways. Scalar data may exist as local variables, in fields of structures, or on the evaluation stack of the abastract machine. Aggregate data exists only in dynamiclly allocated objects which are automatically collected when they are no longer accessible. References of these objects may be stored in local variables, in fields or on the evaluation stack as with other scalars.
      

  45.   

    摘自Stacking them up: a Comparison of Virtual Machines, K John Gough, [email protected]
    该paper探讨了JVM,.NET虚拟机的原理
      

  46.   

    显然是2 这个是refrence的问题。
    总共产生了3个对象。
    运行到9行时,对前两个对象的引用都不存在了,所以会被回收。而第三个的引用数量是2 ,显然不会被回收线程处理掉
      

  47.   

    x指向的对象和另一个是x2与x3指向相同的对象,
    所以应该是两个
      

  48.   

    我想是C 2个吧
    因为一共new了3个.
    在9 行后
    x2,x3都指向了同一个对象.x2.xt x3.x都是NullPoint
    其它两个没人引用了小弟是做C++的  只会一点Java
    错了大家见凉!
      

  49.   

    肯定是2个,但new出来的对象没有指向他的引用时就成为了垃圾
    最后x2,x3都指向了第三个创建的,所以第一,二个创建的已经没有指向他们的引用了,所以称为了垃圾
      

  50.   

    呵呵,和jvm的垃圾收集算法有关系。
    以前有那种非常简单的垃圾收集算法。就是检查对象上还有多少引用,如果为0,则回收。本题
    如果按这种经典的算法,结果是:0个对象被回收。
    但是,在现代的jvm中,垃圾收集算法主要是:从运行栈上开始,往下找,凡是能够被引用到的
    对象才是活对象,不能被回收,否则,被回收。
      

  51.   

    我也同意两个
    1.class MockObject{
    2.         public MockObject x;
    3.         public static void main(String[] args){
    4.         MockObject x2=new MockObject();
    5.         MockObject x3=new MockObject();
    6.         x2.x=x3;
    7.         x3.x=x2;
    8.         x2=new MockObject();
    9.         x3=x2;
    10.         doComplexStuff();
    11.}
    12.}
    首先要改一下类名,不能X2,否则太迷惑人。第八行彻底丢弃了原来申明的x2和x3。还有就是关于垃圾回收,虽然java规范说不能保证立即回收,但如果用java profiler查看一个java程序的运行状态的话,可以发现,垃圾回收实际上是非常频繁的,没几十毫秒就要做一次。
      

  52.   

    这个题目就是考察java中的垃圾回收器的概念:
    在java中你不必想c++中一样显示的释放你在堆中申请的空间(new),垃圾回收器可以帮你在背后自动释放你不需要的空间----一个类实例(对象)所占的空间.当一个对象不被引用时候满足被垃圾回收器回收的条件.注意,垃圾回收器是在一定条件下才启动.他可能随时启动,也可能在程序运行期间永远不启动.根据上述在执行第9行之后,堆中的每个对想都被引用,所以,答案是0.
      

  53.   

    4.         X2 x2=new X2();
    5.         X2 x3=new X2();这两个被回收了~~~
    我是这么认为的~~====CSDN 小助手 V2.0 2005年10月16日发布====
    CSDN小助手是一款脱离浏览器也可以访问Csdn论坛的软件
    界面:http://blog.csdn.net/Qqwwee_Com/archive/2005/10/16/504620.aspx
    下载:http://szlawbook.com/csdnv2/csdnv2.rar为神六喝彩,向所有科技工作者致敬!
    拒绝日货。
      

  54.   

    应该是两个,《Think in java》中文版(第二版 候捷译)216页有这么一段话:
    从stack或static storage出发,走访所有references之后,便能找到所有存在对象,针对你所找到的references,你都必须再钻进它所代表(指向)的对象,然后循着该对象内含的所有references,再钻入他们所指对象,如此反复进行,直到访遍根源于stack或static storage上的references所形成的整个网络为止。你所走访的每个对象都必须是存活的。。根据以上说明,,其他对象就是符合垃圾回收条件的。另java从heap空间分配所有对象,所以对象references存在于堆中。故该题答案为2。
      

  55.   

    所以对象references存在于堆中,
    意思是指对象中的成员references存在于堆中
      

  56.   

    顶,小弟刚入门,说错了请大家见凉!
     我也认为是2个,共穿创建了3 个对象,最后只存在一个了,2个对象为NULL。
    不过我同意楼上大哥说的,我对finalize不是蛮信任。要它去回收垃圾是不能由我们控制的,它是自动调用的(在你的内存不够时)。
           不过还是谢谢前辈指导,受益不少,谢谢
      

  57.   


    大多数的朋友都支持2个的答案。但我还是有点糊涂,请大家再指教一下。
    第4、5行new了两个对象;
    第6、7行对象的成员交叉引用了这两个对象;
    第8行又new了一个新的对象,给了局部变量x2,但是原来分配给x2的空间应该并没有立即释放吧。
    第9行又把x2对象赋值给x3,这时原来分配给x3的空间也没有释放。
    第9行结束以后,就应该存在4个X2的对象,只是有两个已经不能访问了。
    那么回收站中应该回收4给对象好像才合理。
      

  58.   


    大多数的朋友都支持2个的答案。但我还是有点糊涂,请大家再指教一下。
    第4、5行new了两个对象;
    第6、7行对象的成员交叉引用了这两个对象;
    第8行又new了一个新的对象,给了局部变量x2,但是原来分配给x2的空间应该并没有立即释放吧。
    第9行又把x2对象赋值给x3,这时原来分配给x3的空间也没有释放。
    第9行结束以后,就应该存在4个X2的对象,只是有两个已经不能访问了。
    那么回收站中应该回收4给对象好像才合理。
      

  59.   

    应该是2,
    在第9行之后执行System.gc(),打印hash码x2,x3,x2.x,x3.x;
    这四个应用,x2与x3应用同一个对象,x2.x和x3.x为空,说名这个两个对象被回收.
      

  60.   

    init :x2=X2@35ce36
    init :x3=X2@757aef
    bt :x2=X2@35ce36
    bt :x3=X2@757aef
    ag :x2=X2@d9f9c3
    end: x2=X2@d9f9c3
    end: x3=X2@d9f9c3
      

  61.   

    When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.我觉得finalize()在这里基本是可行的,虽然JVM的GC机制有不确定性。public class GcTest {
    public GcTest g;
    public static void main(String[] args) {GcTest x2 = new GcTest();
    GcTest x3 = new GcTest();
    x2.g = x3;
    System.out.println(x2);x3.g = x2;
    x2 = new GcTest();
    x3=x2;
    x2=null;
    x3=null;
    System.gc();
    System.out.println(x2);}
    protected void finalize() throws Throwable {
    System.out.println("clear");
    }}
      

  62.   

    1.class X2{
    2.         public X2 x;
    3.         public static void main(String[] args){
    4.         X2 x2=new X2();
    5.         X2 x3=new X2();
    6.         x2.x=x3;
    7.         x3.x=x2;
    8.         x2=new X2();
    9.         x3=x2;
    10.         doComplexStuff();
    11.}
    12.}
    按我的理解也是两个
    第4,5行:创建了两个对象,所以在stack上有两个ref:x2,x3。但CLASS:X2本身就有一个成员x,它也是X2的实例,所以在heap上实际有2个X2对象的空间产生,分别给x2,x3引用(为了方便后面解说,我叫它们为:OBJ1,OBJ2),x2.x和x3.x指向了NULL。
    第6行:x2.x指向了x3(OBJ2)
    第7行:x3.x指向了x2(OBJ1)
    到这里,OBJ1被x2,x3.x同时引用,OBJ2被x2.x,x3同时引用
    第8行:x2又指向了一个新的X2对象,此时heap又多了1个X2对象(到此一共3个,将这个新的对象叫为OBJ3)。它里面的x成员也是指向了null.
    到这里:OBJ1被x3.x引用,OBJ2被x3引用,OBJ3被x2引用,x2.x指向了null。
    第9行:x3指向了x2的引用对象:OBJ3。到这里就很明显了。x3指向OBJ3,x3.x指向了null(和x2的引用一样),那OBJ1和OBJ2都没被引用到,那它们就是GC的目标了。理解不知道是否有误,还请高手指点。
      

  63.   

    引用: yqj2065(严千钧):对象的成员变量的内存分配全部在heap中
    我是这样理解的,stack上放的是一些基础类型变量或者你调用方法时,也会在这里分配空间,在它的作用域结束时,它的空间也就被释放。而在heap上放的都一些对象(或者说是继续自Object的类对象),它们只有在没引用时才会可能被释放空间。还有上面的那些测试代码并不能说明什么问题,因为你的对象即使没有引用也不一定会被释放,测试的结果也有可能是1,也有可能是0。只有当你虚拟内存不够时,GC才会启动,但它也不是全部都释放,它会先释放一部分,到最如果内存还不够时,它才会检查所有对象进行释放,但这样就会影响到效率(时间较长)。
      

  64.   

    还在讨论这个咚咚。http://community.csdn.net/Expert/topic/4412/4412682.xml?temp=.9176752
    中说我是Terminator,还是再讨论讨论。首先的一点,我们不要过于担心GC何时释放垃圾,因为这不是我们能够决定的。一般从程序员的角度看,知道什么对象“可回收”就足够了。至于是否“被回收”的确很复杂。上面一些朋友已经提到了垃圾回收模型,引用记数模型因为存在循环引用问题,绝大多数GC已经放弃了它。但一个程序员判断垃圾的标准,还是“引用全部失效”。
    wingjimmy(不死鸟) 摘录的《Think in java》中文版(第二版 候捷译)216页有这么一段话,告诉我们如何看待“引用全部失效”。
      

  65.   

    finalize()?它是否真正释放内存,我并不关心。
    这个方法在什么时候被调用?当对象被GC判断为不可达的而要被回收时。就是说,我们不管finalize()实际完成了什么,它提供了一条信息,“这个对象是垃圾”。
    大家可以这样测试:
        protected void finalize() throws Throwable {
            System.out.println("真正释放内存?管它呢,"+ this + "是垃圾" );
        }如果该对象已经被回收,则finalize()已经被调用,在我们的测试代码中,这种情况不存在。
      

  66.   

    public class A{
        public A g;
        public static void main(String[] args) {
            System.out.println("1");
    A x2 = new A();
    System.out.println(x2);
            A x3 = new A();
    System.out.println(x3);
            x2.g =  x3;
    System.out.println(x2.g);
            x3.g =  x2;
    System.out.println(x3.g);
    ////////////////////////////////
    System.out.println("2");
    x2 = new A();
    System.out.println(x2);
    System.out.println(x3);
    System.out.println(x2.g);
    System.out.println(x3.g);
    System.gc(); //********* System.out.println("3");
    x3=x2;
    System.out.println(x2);
    System.out.println(x3);
    System.out.println(x2.g);
    System.out.println(x3.g);
    System.gc(); /*System.out.println("4");
    x2= new A();
    System.out.println(x2);
    System.out.println(x2.g);
    System.gc();*/
    }
        @Override
        protected void finalize() throws Throwable {
    super.finalize();
            System.out.println("真正释放内存?管它呢,"+ this + "是垃圾" );
        }
    }1
    A@11b86e7
    A@35ce36
    A@35ce36
    A@11b86e7
    2
    A@757aef
    A@35ce36
    null
    A@11b86e7
    3
    A@757aef
    A@757aef
    null
    null
    真正释放内存?管它呢,A@35ce36是垃圾
    真正释放内存?管它呢,A@11b86e7是垃圾
    请按任意键继续. . .
      

  67.   

    本人觉得其实很简单:
     public static void main(String[] args){
    4.         X2 x2=new X2();
    5.         X2 x3=new X2();
    6.         x2.x=x3;
    7.         x3.x=x2;
    8.         x2=new X2();
    9.         x3=x2;
    10.         doComplexStuff();
    11.}前面new了两个:X2 x2=new X2(); X2 x3=new X2(); 之后又把x2new了一次,x2=new X2()。说到底,还是x2和x3两个。其他的要么回收了,要么只是做了指针变量而已。
    不要被其他的东西迷惑了!~~~~~~~~~~~:)
      

  68.   

    X2 x2=new X2(); X2 x3=new X2();==》x3指向x2==》x2=new X2()后原x2和x3都会被回收