简体   繁体   中英

Garbage Collection Details: Is this object eligible for GC?

I suppose that a program like this...

class Test {
    public static void main(String[] args) {
        new Test();
        System.out.println("done");
    }

    protected void finalize() {
        System.out.println("this object is known to never be referenced.");
    }
}

...may possibly output "this object is known to never be referenced." before "done" . (Correct me if I'm wrong here!)

Furthermore, it is easy for a compiler/JVM to detect "unread locals". In the program below for instance, Eclipse notices that " The local variable t is never read ".

However would it be illegal for the JVM to output "this object is known to never be referenced." before "done" given the (.class version) of the program below?

class Test {
    public static void main(String[] args) {
        Test t = new Test();
        System.out.println("done");
    }

    protected void finalize() {
        System.out.println("this object is known to never be referenced.");
    }
}

Most documentation of garbage collection talk about reachability. Given the fact that t is never read, the object is obviously not "reachable", or?

References to the JLS are appreciated.

In 12.6.1 of the Java Language Specification says:

12.6.1 Implementing Finalization

Every object can be characterized by two attributes: it may be reachable, finalizer- reachable, or unreachable, and it may also be unfinalized, finalizable, or finalized. A reachable object is any object that can be accessed in any potential continuing computation from any live thread. Optimizing transformations of a program can be designed that reduce the number of objects that are reachable to be less than those which would naively be considered reachable.

For example, a compiler or code generator may choose to set a variable or parameter that will no longer be used to null to cause the storage for such an object to be potentially reclaimable sooner.

The last phrase seems to me covering exactly the case you are asking about. The variable t can be set to null implicitly before the end of the scope, therefore making the object unreachable.

This in C++ would be a disaster because a lot of code depends on exact destruction timing at the end of scope (eg for locks).

...may possibly output "this object is known to never be referenced." before "done".

There are three possible behaviors:

  • the message is output before "done",

  • the message is output after "done",

  • the "this object is known to never be referenced" message is not output at all.

(In practice, the most likely behavior is that the last one. In fact, it is a virtual certainty unless you generate lots of garbage between creating the Test instance and printing "done".)

However would it be illegal for the JVM to output "this object is known to never be referenced." before "done" given the (.class version) of the program below?

No it would not be illegal. The Test instance cannot "be accessed in any potential continuing computation from any live thread" , and is therefore unreachable. Therefore it would be legal for the JVM to garbage collect it and finalize it immediately.

However, three events that must happen for the message to appear:

  • the GC has to run,
  • the GC has to detect the object as unreachable, and
  • the GC has to finalize the object.

There is no guarantee that all of these events will happen before the application exits, yet alone in the window between creating the instance and printing "done".


The bottom line is that you should never depend on finalization occurring in a Java application.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM