我正在阅读 Thinking in Java,4th Edition 。我发现了一个问题:当我在Eclipse IDE中测试源代码时,我发现结果是不同的。我希望有人可以帮助我!
以下是源代码
class Book {
boolean checkedOut = false;
Book(boolean checkOut) {
checkedOut = checkOut;
}
void checkIn() {
checkedOut = false;
}
protected void finalize() {
if(checkedOut)
System.out.println("Error:checked out");
//Normally,you'll also do this:
//super.finalize();//Call the base-class version
}
}
public class TerminationCondition {
public static void main(String[]args) {
Book novel=new Book(true);
//Proper cleanup:
novel.checkIn();
//Drop the reference,forget to clean up:
new Book(true);
new Book(true);
new Book(true);
//Force garbage collection & finalization:
System.gc();
}
}
本书的结果:
Error: Checked out
IDE的结果
(nothing)
我使用的Java版本:
Java版“1.7.0_51”
Java(TM)SE运行时环境(版本1.7.0_51-b13)
Java HotSpot(TM)64位服务器VM(内置24.51-b03,混合模式)
本书中的Java版本是Java 5.有关finalize方法的更改吗?
答案 0 :(得分:1)
JVM有自己的垃圾收集管理策略,即使你单独调用finalize()
也不是! JVM做得非常好,用户无需干预垃圾内存清理过程。
所以,你所观察到的与Java版本或任何东西无关!它完全取决于JVM及其自动内存管理策略。
答案 1 :(得分:0)
运行GC之前,主线程正在退出。所以你没有得到任何输出。在主方法中执行以下更改,您将看到输出: -
System.gc();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
答案 2 :(得分:0)
本书中的Java版本是Java 5.有关finalize方法的更改吗?
如果您阅读了System.gc()
及相关事项的规范,您会发现几乎没有任何关于将要发生的事情的保证:
无法保证调用System.gc()
会导致发生任何事情。严重。
不保证会收集所有垃圾。
无法保证垃圾对象最终确定......不能使用finalize()
方法。
这里真正的问题是你正在考虑的例子是无根据的假设。它恰好适用于旧版本的Java。它不适用于最近的......或类似的东西。这只是一个坏的例子。
但这确实(我希望)向你展示依靠在可预测的时间调用的finalize
方法 unwise 。事实上,最好不要将finalize
用于任何事情......除了"腰带和牙套"整理代码。
事实上,在垃圾收集器完成后,通常会发生。 (它由一个守护进程"终结线程"完成所有已被识别为无法访问的对象,并且需要最终确定。)因此,您的示例中可能发生的事情是JVM退出之后GG已经运行,但在终结线程有机会处理可终结的对象之前。