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或任何线程或引用变量无法访问,则应由垃圾收集器收集。
有人可以用更好的例子和更精确的方式帮助我理解上述程序的微妙之处吗?感谢您的帮助。
答案 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
,而对b1
和b2
的情况存在对这些对象的其他引用,这些对象尚无法收集
答案 3 :(得分:1)
这里有几个误解
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