java中的垃圾收集示例?

时间:2012-08-01 14:11:57

标签: java garbage-collection

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或任何线程或引用变量无法访问,则应由垃圾收集器收集。

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

5 个答案:

答案 0 :(得分:7)

因为b1和amp;指向的对象仍然存在参考。 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的条件。

答案 1 :(得分:1)

  • b2不适用于gc,因为它仍然有一个引用a2.b2
  • b1不适用于gc,因为Alpha.b1拥有对它的引用(Alpha.b1是静态的,不要混淆,因为它是使用a1.b1设置的)

答案 2 :(得分: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的情况存在对这些对象的其他引用,这些对象尚无法收集

答案 3 :(得分:1)

这里有几个误解

  • GC仅在需要时运行。要比不需要更频繁地执行GC,就可以完成它不需要的工作。
  • a1.b1实际上是Alpha.b1,因为实例并不重要,甚至null使用al.b1也很容易让人感到困惑。
  • a1.b2应该抛出NullPointerException,因为a1是null
  • Alpha.b1已设置但未在任何位置清除,因此它引用的对象不符合清除条件。可以清除其他对象但不明确调用System.gc();,它不太可能需要在您可能期望的位置运行。
  • a1已清除但a2不是,因此不会被清除(直到方法返回)

答案 4 :(得分:0)

垃圾收集示例

getLineDir :: (Int, Int) -> Piece -> Board -> [Piece]
getLineDir (x, y) (Piece (x', y') player) board 
            | pieceAt(x'+ x, y'+ y) board == Nothing = []
            | pieceAt(x'+ x, y'+ y) board == Just (Piece _ player') && isPlayer player (Piece _ player') == True = (Piece (x', y') player) : [] 
            | otherwise  = (Piece _ player') : getLineDir (x,y) (Piece (x'+ x, y'+ y) player) board

节目输出:

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

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