为了账号安全,请及时绑定邮箱和手机立即绑定

“对于任何给定对象,JVM 永远不会多次调用 finalize 方法”的含义。在物体复活的情况下?

“对于任何给定对象,JVM 永远不会多次调用 finalize 方法”的含义。在物体复活的情况下?

慕桂英4014372 2021-11-17 12:30:53
根据 Java 文档:对于任何给定对象,Java 虚拟机永远不会多次调用 finalize 方法。上述政策可以帮助使对象不朽吗?如果我从 finalize() 方法中一次复活一个对象,那么该对象是否会成为不朽的,因为 JVM 不能第二次在该对象上调用 finalize() 方法?或者如果该对象再次符合 GC 条件(假设指向复活对象的另一个引用符合 GC 条件),那么下次 JVM 将删除该对象而不调用该对象的 finalize() 方法?我试图通过一些示例代码来验证它并假设第二个是正确的,但需要确认我的理解。
查看完整描述

1 回答

?
慕斯王

TA贡献1864条经验 获得超2个赞

根据 ernest_k,它是第 2 个。该对象将被垃圾收集,而无需调用其 finalize() 方法。


添加我的示例代码来完成这个答案,我创建它来验证。


import java.util.HashSet;

import java.util.Set;


class Immortal {


    // making it public and non-fianl to modify from outside

    public static Set<Immortal> immortals = new HashSet<>();


    @Override

    protected void finalize() throws Throwable {

        System.out.println("Running finalize for " + this);

        immortals.add(this); // Resurrect the object by creating a new reference

    }

}


public class ObjectResurrection {


    public static void callGC() {

        // call garbage collection

        System.gc();


        // wait for some time to give chance to run garbage collection thread

        try {

            Thread.sleep(10 * 1000);

        } catch (InterruptedException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }


    public static void main(String[] args) {

        Immortal immortal1 = new Immortal();

        Immortal immortal2 = new Immortal();


        // print objects when they are alive.

        System.out.println("immortal1 = " + immortal1);

        System.out.println("immortal2 = " + immortal2);


        // print immortal set

        System.out.println("immortal set = " + Immortal.immortals);


        // make all objects garbage collectable

        immortal1 = null;

        immortal2 = null;


        callGC();


        // now objects will be null

        System.out.println("immortal1 = " + immortal1);

        System.out.println("immortal2 = " + immortal2);


        // but stays in immortal set

        System.out.println("immortal set = " + Immortal.immortals);


        // remove all objects from immortal set, and make them again eligible for GC

        Immortal.immortals.clear();


        callGC();


        // again print the immortal set

        // this time set will be empty, and those 2 objects will be destroyed by Garbage

        // Collection,

        // but this time they will not call finalize, because it is already called

        // you can notice no output from finalize method in the output this time

        System.out.println("immortal set = " + Immortal.immortals);

    }


}

上述程序的输出(在我的机器上):


immortal1 = effective.java.item7.finalizer6.Immortal@70dea4e

immortal2 = effective.java.item7.finalizer6.Immortal@5c647e05

immortal set = []

Running finalize for effective.java.item7.finalizer6.Immortal@5c647e05

Running finalize for effective.java.item7.finalizer6.Immortal@70dea4e

immortal1 = null

immortal2 = null

immortal set = [effective.java.item7.finalizer6.Immortal@5c647e05, effective.java.item7.finalizer6.Immortal@70dea4e]

immortal set = []


查看完整回答
反对 回复 2021-11-17
  • 1 回答
  • 0 关注
  • 288 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信