Java对象复活

总览

收集覆盖了finalize()的对象之后,将其添加到终结处理队列中,以在调用每个对象的finalize()方法之后进行清理。 如果您复活该物体,会发生什么?

何时定稿?

finalize方法由单线程系统任务调用,该任务针对已收集的每个对象调用此方法。 注意:终结队列中的节点是对象,概念上也具有finalize()方法。 对象完成后才能清理对象。

大多数对象(包括终结队列中的节点)不会覆盖finalize(),因此GC足够智能,可以检测到该事件,而不将其添加到队列中。 这些对象可以立即清除。 如果覆盖该方法,即使使用空方法,也会有所不同。

那复活的物体呢?

在finalize()方法中,您可以通过使对象指向某点来复活该对象。 例如静态集合。 GC不再可以收集该对象(直到再次丢弃),那么会发生什么呢?

该对象已被标记为已完成一次且不会重复完成。

static final List ZOMBIES = new ArrayList<>();
    static class Zombies {
        private int num;
        public Zombies(int num) {
            this.num = num;
        }
        @Override
        protected void finalize() throws Throwable {
            System.out.println("Resurrect " + num);
            ZOMBIES.add(this);
        }
        @Override
        public String toString() {
            return "Zombies{" + "num=" + num + '}';
        }
    }
    public static void main(String... args) throws InterruptedException {
        for (int i = 0; i < 3; i++)
            ZOMBIES.add(new Zombies(i));
        for (int j = 0; j < 5; j++) {
            System.out.println("Zombies: " + ZOMBIES);
            ZOMBIES.clear();
            System.gc();
            Thread.sleep(100);
        }
    }
版画
Zombies: [Zombies{num=0}, Zombies{num=1}, Zombies{num=2}]
Resurrect 2
Resurrect 1
Resurrect 0
Zombies: [Zombies{num=2}, Zombies{num=1}, Zombies{num=0}]
Zombies: []
Zombies: []
Zombies: []

在此示例中,僵尸一次添加到集合中,并通过finalize方法重新复活一次。 当第二次收集它们时,它们已标记为已完成并且不再排队。

结论

避免使用finalize()是个好主意,但要知道它仅在对象复活后才被调用,这是一个小小的安慰。

参考:来自Vantage Java博客的JCG合作伙伴 Peter Lawrey的Java Object resurrection

翻译自: https://www.javacodegeeks.com/2012/12/java-object-resurrection.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值