Java 垃圾收集详细信息:此对象符合GC条件吗?
我想像这样的程序Java 垃圾收集详细信息:此对象符合GC条件吗?,java,garbage-collection,Java,Garbage Collection,我想像这样的程序 class Test { public static void main(String[] args) { new Test(); System.out.println("done"); } protected void finalize() { System.out.println("this object is known to never be referenced."); } } …可能
class Test {
public static void main(String[] args) {
new Test();
System.out.println("done");
}
protected void finalize() {
System.out.println("this object is known to never be referenced.");
}
}
…可能会输出“已知此对象从未被引用过。”
在“完成”
之前。(如果我错了,请纠正我!)
此外,编译器/JVM很容易检测到“未读局部变量”。例如,在下面的程序中,Eclipse注意到“从未读取局部变量t”
但是如果JVM输出“已知此对象从未被引用过。”
在“完成”
之前,给定以下程序的(.class版本),这是否是非法的?
class Test {
public static void main(String[] args) {
Test t = new Test();
System.out.println("done");
}
protected void finalize() {
System.out.println("this object is known to never be referenced.");
}
}
大多数垃圾收集文档都讨论可达性。鉴于t
从未被读取,对象显然无法“访问”,或者
请参考JLS。中的说明:
12.6.1实施最终定稿
每个物体都有两个特征
属性:它可能是可访问的,
终结器-可访问或不可访问,
而且它也可能是未完成的,
可定稿的,可定稿的。可达的
对象是任何可以
在任何可能的情况下访问
从任何活动线程进行计算。
优化一个函数的变换
程序可以设计为减少
要删除的对象数
可到达的小于那些
会天真地被认为是可达的
例如,编译器或代码
生成器可以选择设置变量
或将不再使用的参数
用于null以导致存储为
这样一个对象可能是
可以更快地回收
在我看来,最后一句话似乎完全涵盖了你所问的情况。变量t
可以在作用域结束之前隐式设置为null
,从而使对象无法访问
<>这在C++中会是一个灾难,因为很多代码取决于范围结束时的精确销毁定时(例如对于锁)。
…可能会在“完成”之前输出“已知此对象从未被引用”
有三种可能的行为:
- 消息在“完成”之前输出
- 消息在“完成”之后输出
- “已知此对象从未被引用”消息根本不会输出
Test
实例和打印“done”之间产生大量垃圾,否则这是一个虚拟的确定性行为。)
但是,在给定以下程序的(.class版本)的“完成”之前,JVM输出“已知此对象从未被引用”是否非法
不,这并不违法。Test
实例无法“在任何活动线程的任何潜在连续计算中访问”,因此无法访问。因此,JVM对其进行垃圾收集并立即完成是合法的
但是,要显示消息,必须发生三个事件:
- GC必须运行
- GC必须将对象检测为不可访问,并且
- GC必须完成对象
底线是,您永远不应该依赖于Java应用程序中发生的终结。至少在C#/.net中是这样。即使在第二个程序中,对象的终结也可能发生在“完成”消息之前。这是因为抖动可以自由地优化变量,一旦它明确不再被访问。啊哈,很有趣。也许Java也是如此。不过我目前还不确定。嗯,在Java.Yep中似乎是类似的。完全正确好发现。谢谢!对谢谢我知道“根本没有输出”。这就是我测试它时所发生的情况:-)这就是为什么我将它表述为“JVM……这是否是非法的……”aioobe回答,我相信。啊,是的。有了JLS的报价,事实上非常清楚!再次感谢。我已经很久没用Java了。。。但在当时,由于所有程序只是将计算机置于垃圾模式,GC显然从未找到对象:-D@6502-那是什么版本的Java?如果你说的是Java1.0,它在1997年就被淘汰了。