java终结方法_java终结器和gc

是时候质疑JAVA System.GC()和System.runFinilizer了

public interface SomeAction {

public void doAction();

}

public class SomePublisher {

private List actions = new ArrayList();

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和终结器.

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.

(System.GC和终结器强制至少为’1′.)

相反,它始终为0.

谁能解释这种行为?

(另外,静态成员字段是否与类实例无关,并且在代码执行期间永远不会被销毁?)

最佳答案 你的测试有一个缺陷 – 即使假设调用System.gc()和System.runFinalization()实际上会运行GC并完成,你创建的实例也不是垃圾收集的候选者,因此,不会最终确定或收集.

你运行这行10次:

SomeSubscriber subscriber = new SomeSubscriber(publisher);

这会调用SomeSubscriber的构造函数,它说:

publisher.subscribe(this);

因此,发布者对象被赋予对当前正在构造的对象的引用.它有什么作用?

actions.add(subscriber.getAction());

好的,所以它调用订阅者的getAction()方法,并存储结果. getAction()做什么?

public SomeAction getAction() {

final SomeSubscriber me = this;

class Action implements SomeAction {

@Override

public void doAction() {

me.doSomething();

}

}

return new Action();

}

它创建一个本地类的实例.该实例包含封闭SomeSubscriber对象的实例.实际上,它有两个这样的实例 – 我,以及每个内部类具有的封闭实例的隐式引用.本地课程是内部课程!

因此,当您在发布者实例中存储操作列表时,还会存储对其中所有订阅者的引用.当您运行System.gc()和System.runFinalization()时,发布者实例仍处于活动状态,因此这些引用仍然存在,因此您的SomeSubscriber实例中没有一个实际符合垃圾回收的条件.

确保你还分配publisher = null,然后你可能会看到正在运行的终结.我还建议将Count声明为volatile(并且不要将其称为Count但计数 – 变量应该以小写字母开头),因为终结器通常在不同的线程中运行.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值