4
class Beta { }

class Alpha {
static Beta b1  ;
Beta b2;
}

public class Tester {

public static void main(String[] args) {

    Beta b1 = new Beta();
    Beta b2 = new Beta();
    Alpha a1 = new Alpha();
    Alpha a2 = new Alpha();

    a1.b1 = b1 ;
    a1.b2 = b1 ;
    a2.b2 = b2 ;

    a1 = null ;
    b1 = null;
    b2 = null;

    System.out.println(" Line 1    " + " a1   "  + a1.b1);
    System.out.println(" Line 2    " + " a1   "  + a1.b2);
    System.out.println(" Line 3    " + " a2   " + a2.b2);
    System.out.println(" Line 4    " + " a1   " + a2.b1);
    System.out.println(" Line 5    " + " b1   " + b1);
    System.out.println(" Line 6    " + " b1   " + b2);

  }

 }  

我不确定为什么上述程序中只有 a1 对象可用于垃圾收集。我期待垃圾收集器收集 a1 、 b1 和 b2 。

正如您所看到的 a1 , b1 和 b2 被设为 NULL 因此这使得对象可用于垃圾收集。如果对象为 NULL 或任何线程或引用变量都无法访问,则它应该由垃圾收集器收集。

有人可以通过很好的例子和更精确的方式帮助我理解上述程序的微妙之处吗?感谢您的帮助。

4

5 回答 5

8

因为由于下面的行,仍然存在对 b1 和 b2 引用所指向的对象的引用。

a1.b1 = b1 ;
a1.b2 = b1 ;
a2.b2 = b2 ;

假设这样:

  b1--->BetaObj1
    b2---BetaObj2
    a1---> AlphaObj1
    a2---> AlphaObj2

a1.b1 指向 b1 表示存在对 BetaObj1 的引用 a1.b2 指向 b1 表示存在另一个对 BetaObj1 的引用

(此时有3个对BetaObj1的引用)

a2.b2 指向 b2 这意味着,有对 BetaOBj2 的引用

(此时有2个对BetaObj2的引用)

a1=null;使 AlphaObj1 符合 GC 条件

b1=null;使 BetaObj1 引用计数为 2,因此该对象不符合 GC 条件

b2=null;使 BetaObj2 引用计数为 1,因此该对象不符合 GC 条件。

于 2012-08-01T14:15:11.457 回答
1
  • b2不适用于 gc,因为仍有a2.b2对其的引用
  • b1对 gc 不可用,因为Alpha.b1拥有对它的引用(Alpha.b1是静态的,不要混淆,因为它是使用设置的a1.b1
于 2012-08-01T14:17:09.893 回答
1

你应该在这里得到一个NullPointerException

System.out.println(" Line 1    " + " a1   "  + a1.b1);
System.out.println(" Line 2    " + " a1   "  + a1.b2);

此时,a1已设置为null,因此无法访问其成员,b2因为它不再引用对象。(访问静态b1作品,因为这只需要类,而不是实例。)

正如您所看到的 a1 , b1 和 b2 被设为 NULL 因此这使得对象可用于垃圾收集。

不,您将对这些对象的一些引用设置为null,而对这些对象的其他引用存在,就像 和 的情况一样b1b2这些对象还不能被收集。

于 2012-08-01T14:18:49.120 回答
1

这里有几个误解

  • GC 仅在需要时运行。比需要更频繁地执行 GC 将做它不需要的工作。
  • a1.b1实际上Alpha.b1,因为实例并不重要,甚至可以null使用al.b1,这简直令人困惑。
  • a1.b2应该像 a1 一样抛出 NullPointerException null
  • Alpha.b1已设置但未在任何地方清除,因此它引用的对象不符合清除条件。可以清理其他对象,但无需System.gc();显式调用,它极不可能需要在您期望的位置运行。
  • a1被清除但a2不是所以它不会被清除(直到方法返回)
于 2012-08-01T14:43:58.360 回答
0

垃圾收集示例

public class GarbageCollection {

    public static void main(String s[]) throws Exception  {
          Runtime rs =  Runtime.getRuntime();
          System.out.println("Free memory in JVM before Garbage Collection = "+rs.freeMemory());
          rs.gc();
          System.out.println("Free memory in JVM after Garbage Collection = "+rs.freeMemory());
       }
}

程序输出:

垃圾回收前 JVM 中的可用内存 = 62767488

垃圾收集后 JVM 中的可用内存 = 62854120

于 2016-05-30T08:44:48.970 回答