我有一个问题让我很困惑,
运行以下代码的第8行后,哪些对象有资格进行垃圾回收?
public class X
{
public static void main(String [] args)
{
X x = new X();
X x2 = m1(x); /* Line 6 */
X x4 = new X();
x2 = x4; /* Line 8 */
doComplexStuff();
}
static X m1(X mx)
{
mx = new X();
return mx;
}
}
A .X
B .x和x2
C .x和x4
的 d .x4
我最初的想法是只有x2被垃圾收集,因为当x2 = x4时它在第8行被引用,并且因为java是按值传递的,所以X x2 = m1(x)不会影响x。
我在这里https://www.indiabix.com/java-programming/garbage-collections/discussion-202也找到了完全相同的问题(但是选择不同),并且有些评论说x也应该被垃圾收集,这与我的想法相矛盾,现在我很困惑哪个这个问题的选择是正确的,提前谢谢。
答案 0 :(得分:2)
许多人已回答x2引用的对象是垃圾收集。 下面是一个示例代码,允许您自己检查GC,此代码还演示了Java的行为:
Java通过引用操作对象,但它按值将对象引用传递给方法。
public class GCInJava
{
int i=0;
String name="default";
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("[GCing object referenced by: "+this.name+"]");
}
public static void main(String [] args)
{
GCInJava x = new GCInJava();
x.name="x";
System.out.println("x before calling m1(): "+x);
System.out.println("x.i before calling m1(): "+x.i);
GCInJava x2 = m1(x);
System.out.println("x.i after calling m1(): "+x.i);
System.out.println("x after calling m1(): "+x);
System.out.println("x2.i: "+x2.i);
GCInJava x4 = new GCInJava();
x4.name="x4";
x2 = x4;
System.gc();
doComplexStuff();
}
static GCInJava m1(GCInJava mx)
{
System.out.println("mx before new object: "+mx);
mx = new GCInJava();
mx.i=10;
mx.name="mx/x2";
System.out.println("mx after new object: "+mx);
return mx;
}
}
注意: System.gc()
可能并不总是通过JVM触发垃圾回收;所以尝试运行几次代码。
示例输出(注意打印的哈希码):
在调用m1()之前:tests.GCInJava@64c3c749
x.i在调用m1()之前:0 新对象之前的mx:tests.GCInJava@64c3c749
新对象后的mx:tests.GCInJava@7150bd4d
调用m1()后的x.i:0 调用m1()后的x:tests.GCInJava@64c3c749
x2.i:10[引用的GCing对象:mx / x2]
答案 1 :(得分:1)
我认为这不是一个特别好的问题。
首先, 变量不符合垃圾收集的条件,对象可以。 所以说x2
符合GC的条件意味着什么,因为那时候我可以说mx
也符合条件,因为该方法已返回。这使得它看起来好像内存中的对象多于实际对象。
这更准确
第12行创建的对象符合GC的条件。
此外,第5行创建的对象不符合条件,x
仍在引用它。只需尝试打印x
中的值。你会发现它不是空的。
答案 2 :(得分:0)
是的,你是对的。
Java是"传递值",只有mx
,mx = new X();
被垃圾收集。
x
并非垃圾收集。例如;
public class X
{
public static void main(String [] args)
{
X x = new X();
X x2 = m1(x);
X x4 = new X();
x2 = x4;
doComplexStuff();
System.out.print(x); // no problem; line 10
}
static X m1(X mx)
{
mx = new X();
return mx;
}
}
如果x
被垃圾收集,则第10行是错误的。事实上,事实并非如此。
因此,x
不是垃圾回收