【发布时间】:2017-02-11 05:28:25
【问题描述】:
是时候质疑 JAVA System.GC() 和 System.runFinilizer
public interface SomeAction {
public void doAction();
}
public class SomePublisher {
private List<SomeAction> actions = new ArrayList<SomeAction>();
public void subscribe(SomeSubscriber subscriber) {
actions.add(subscriber.getAction());
}
}
public class SomeSubscriber {
public static int Count;
public SomeSubscriber(SomePublisher publisher) {
publisher.subscribe(this);
}
public SomeAction getAction() {
final SomeSubscriber me = this;
class Action implements SomeAction {
@Override
public void doAction() {
me.doSomething();
}
}
return new Action();
}
@Override
protected void finalize() throws Throwable {
SomeSubscriber.Count++;
}
private void doSomething() {
// TODO: something
}
}
现在我正在尝试在主块中强制 GC 和 Finalizer。
SomePublisher publisher = new SomePublisher();
for (int i = 0; i < 10; i++) {
SomeSubscriber subscriber = new SomeSubscriber(publisher);
subscriber = null;
}
System.gc();
System.runFinalization();
System.out. println("The answer is: " + SomeSubscriber.Count);
由于不保证调用 JAVA GC 调用(如 javadoc 中所述,并且由于不保证调用 JAVA GC 调用(如 javadoc 和 When is the finalize() method called in Java? 中所述,
我的初始想法是它会随机输出 SomeSubscriber.Count。 (至少 '1' 作为 System.GC 和终结器的强制。)
相反,它始终为 0。
谁能解释这种行为?
(另外,静态成员字段是否独立于类实例而存在,并且在代码执行期间永远不会被破坏?)
【问题讨论】:
-
如果你不知道什么是静态字段,你不应该担心终结器或 gc。
-
静态字段是类变量,不实例化类实例共享的类而存在。
-
“不保证被调用”的哪一部分你没看懂?
-
你不应该明确地调用
System.gc()。在最好的情况下,它什么也不做,在最坏的情况下,它总是会导致完全停止世界的 GC(例如,当 CMS 收集器正在使用时)。 -
如果您看到来自stackoverflow.com/questions/2506488/… 的 techloris_109 示例,则会手动调用 System.GC() 并在将实例清空后完成块运行。为什么我的情况没有发生同样的事情?
标签: java garbage-collection finalizer