如果我再次使 "finalized" 对象可用,它会发生什么情况?

What happens to a "finalized" object if I make it available again?

好吧,我尝试使 最终化 对象再次可用。我知道(来自 oracle docsfinalize() 不会再被调用。但是如果它变成 unreachable 会发生什么? 什么时候进行GC?.

代码:

public class Solution {
static ThreadGroup stg = null;
static Solution ss = null;

protected void finalize() throws Throwable {
    System.out.println("finalized");
    System.out.println("this : " + this);
    ss = this;

}

public static void main(String[] args) {
    Solution s = new Solution();
    s = null;
    System.gc();
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    System.out.println(ss);
    ss = null;             // My question. What happens now?. Solution@7f5f5897 has just become unreachable. Will it be GCed without "finalize()" being called on it? (looks like that..). If yes, then how can I find out when exactly has it become eligible for gc (Please don't tell me to look at source code "==null" check :P)
    System.gc();
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

O/P :

finalized
this : Solution@7f5f5897   // printed in finalize()
Solution@7f5f5897  // printed in main()

是的,一旦它第二次变得无法访问,它将被 GC 处理,除了 finalize 不会再次调用它。

您可以用 WeakReference 确认这一点。

static WeakReference<Solution> ref;

public static void main(String[] args) {
    Solution s = new Solution();

    s = null;
    System.gc();
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    System.out.println(ss);
    ref = new WeakReference<Jackson>(ss);
    ss = null; // My question. What happens now?. Solution@7f5f5897 has just become unreachable. Will it be GCed without "finalize()" being called
               // on it? (looks like that..). If yes, then how can I find out when exactly has it become eligible for gc (Please don't tell me to
               // look at source code "==null" check :P)
    System.out.println(ref.get()); // (hopefully) prints object
    System.gc();
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println(ref.get()); // prints null
}

因此 WeakReferenc 被清除,表明该对象已被 GC 处理。 (从技术上讲,当对象变得弱可达时,WeakReference 会被清除。但在这种情况下,由于您无法使其可达,它将被 GC 处理。)