先决条件—— Java中的垃圾收集
难度等级: 中间的 在Java中,对象销毁由 垃圾收集器 模块和没有任何引用的对象都有资格进行垃圾收集。下面是一些关于垃圾收集的重要输出问题。 预测以下Java程序的输出:
- 项目1:
public
class
Test
{
public
static
void
main(String[] args)
throws
InterruptedException
{
String str =
new
String(
"GeeksForGeeks"
);
// making str eligible for gc
str =
null
;
// calling garbage collector
System.gc();
// waiting for gc to complete
Thread.sleep(
1000
);
System.out.println(
"end of main"
);
}
@Override
protected
void
finalize()
{
System.out.println(
"finalize method called"
);
}
}
输出:
end of main
说明: 我们知道 定稿 方法在销毁对象之前由垃圾收集器调用。但在这里,诀窍在于str是字符串类对象,而不是测试类。因此,String类的finalize()方法(如果在String类中被重写)在str上被调用。如果一个类没有重写finalize方法,则默认情况下调用Object class finalize()方法。
- 项目2:
public
class
Test
{
public
static
void
main(String[] args)
throws
InterruptedException
{
Test t =
new
Test();
// making t eligible for garbage collection
t =
null
;
// calling garbage collector
System.gc();
// waiting for gc to complete
Thread.sleep(
1000
);
System.out.println(
"end main"
);
}
@Override
protected
void
finalize()
{
System.out.println(
"finalize method called"
);
System.out.println(
10
/
0
);
}
}
输出:
finalize method called end main
说明: 当垃圾收集器对对象调用finalize()方法时,它 忽视 方法和程序中引发的所有异常都将正常终止。
- 方案3:
public
class
Test
{
static
Test t ;
static
int
count =
0
;
public
static
void
main(String[] args)
throws
InterruptedException
{
Test t1 =
new
Test();
// making t1 eligible for garbage collection
t1 =
null
;
// line 12
// calling garbage collector
System.gc();
// line 15
// waiting for gc to complete
Thread.sleep(
1000
);
// making t eligible for garbage collection,
t =
null
;
// line 21
// calling garbage collector
System.gc();
// line 24
// waiting for gc to complete
Thread.sleep(
1000
);
System.out.println(
"finalize method called "
+count+
" times"
);
}
@Override
protected
void
finalize()
{
count++;
t =
this
;
// line 38
}
}
输出:
finalize method called 1 times
说明: 执行第12行后,t1有资格进行垃圾收集。所以,当我们在第15行调用垃圾收集器时,垃圾收集器将在销毁t1之前在t1上调用finalize()方法。但是在finalize方法中,在第38行中,我们再次通过t引用同一个对象,所以在执行第38行之后, 这 对象不再符合垃圾收集的条件。因此,垃圾收集器不会破坏对象。
现在,在第21行中,我们再次使同一个对象符合垃圾收集的条件。在这里,我们必须澄清关于垃圾收集器的一个事实,即它将准确地对特定对象调用finalize()方法 一 时间因为在这个对象上,finalize()方法已经被调用,所以现在垃圾收集器将销毁它,而不再调用finalize()方法。
- 方案4:
public
class
Test
{
public
static
void
main(String[] args)
{
// How many objects are eligible for
// garbage collection after this line?
m1();
// Line 5
}
static
void
m1()
{
Test t1 =
new
Test();
Test t2 =
new
Test();
}
}
问题: 执行第5行后,有多少对象符合垃圾收集条件? 答复:
2
说明: 由于t1和t2是m1()方法的本地对象,所以在方法完全执行后,除非返回其中任何一个,否则它们就有资格进行垃圾收集。
- 方案5:
public
class
Test
{
public
static
void
main(String [] args)
{
Test t1 =
new
Test();
Test t2 = m1(t1);
// line 6
Test t3 =
new
Test();
t2 = t3;
// line 8
}
static
Test m1(Test temp)
{
temp =
new
Test();
return
temp;
}
}
问题: 执行第8行后,有多少对象符合垃圾收集条件? 答复:
1
说明: 到执行第8行时,唯一没有引用的对象是生成的对象,即第6行的结果。记住“ Java严格按值传递 “因此,参考变量t1不受m1()方法的影响。我们可以使用finalize()方法检查它。finalize()方法中的语句“System.out.println(this.hashcode())”打印调用finalize()方法的对象hashcode值,然后将该值与在main方法中创建的其他对象hashcode值进行比较。
本文由 高拉夫·米格拉尼 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄去评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。
如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。