3

This question is a continuation of this one but asking for a more specific scenario.

Lets say we have the following class:

public class Person {
    private Foot left, right;

    public Person(Foot left, Foot right) {
        this.left = left;
        this.right = right;
    }
}

I was wondering if the following class would be able to be optimised from the GC's perspective if we turned it into the following:

public class Person {
    private final Foot left, right;

    public Person(Foot left, Foot right) {
        this.left = left;
        this.right = right;
    }
}

If I was looking at this class I can immediately tell that the left and right variables can never be set to null early. That means that the only time the GC will need to collect the left and right objects (and decrease the references to it) for this class will be when the references to the parent Person class reach zero. It should also mean that it might be able to collect person at the same time as it collects left and right Foot objects; also resulting in less runs and a speedup.

Therefore, in this example, does marking the private member variables final mean that the code will result even a minor speedup in garbage collection (or could it possibly be used as a speedup point)?

Community
  • 1
  • 1
Robert Massaioli
  • 13,379
  • 7
  • 57
  • 73
  • the answers in the previous question seem to pretty definitively state the answer as "no" - is there some part of those answers that is unclear? Otherwise this question sounds almost exactly the same – matt b Jun 07 '11 at 02:26

3 Answers3

7

Assignment to fields does not trigger any garbage collector work or reference count adjustment because Java GCs don't use reference counting (*). So the answer is that declaring a field as final will make no difference to garbage collector performance. (The tracing phase of the collector has to examine the field whether or not it is final.

It is conceivable that declaring a field to be final could help the JIT compiler's data flow analysis and optimization of memory fetches. However, it would be a bad idea to use that as a justification for changing fields to final. If you are going to do it, do it for correctness reasons (i.e. to make construction safe in a concurrent context) or for stylistic reasons (i.e. to make the code easier to understand and maintain).

(* No mainstream Java implementation relies on reference counting to implement memory management. It is theoretically possible that someone might implement a JVM that used reference counting, but conventional wisdom is that reference counting is horribly inefficient ... not to mention problematic for concurrency, collecting cycles, and so on.)

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • _do it for stylistic reasons_ This doesn't sound right. Setting up final fields (regular way, no reflection) is a memory barrier, so that ` the runtime(JVM)` guarantees that the object is properly constructed and the `final field` is properly constructed before the constructor if finished. (guarantees memory visibility). this is very important in multi-threaded programs. – Op De Cirkel Jun 07 '11 at 02:59
  • That response was pretty good. TIL that no Java GC uses reference counting for example. Though Op De Cirkel is right in stating that final fields are useful for ensuring an Immutable object. And I know that setting fields does not trigger garbage collection but what about when the person object, somewhere else in the codebase is set to null and marked for garbage collection. Does not that mean that you could potentially mark both feet too for reaping too? – Robert Massaioli Jun 07 '11 at 03:07
  • 1
    @Robert Massaioli - there is no "marking for garbage collection". The only marking is marking as NOT for garbage collection. AFAIK, there is no opportunity for optimization here. – Stephen C Jun 07 '11 at 03:15
  • Okay then. Thankyou for the comprehensive answer and marking as such. – Robert Massaioli Jun 07 '11 at 03:16
1

The only reason that GC optimization is not possible, is because JVM spec does allow changing final field.
final fields has special semantic during the object construction process which is important for the construction process to work properly regarding the java memory model. But you can break the rules and use reflection to change it. In this case you can not rely on the semantic of final field (regarding the java memory model)

the strike: Sorry guys, i don't know what i was talking about. final is irrelevant for GC. even if final is not changeable at all, GC can not get any useful information of that fact

Op De Cirkel
  • 28,647
  • 6
  • 40
  • 53
  • this is hypothetical. It assumes that there would be some optimization based on `final` fields ... which is not true. – Stephen C Jun 07 '11 at 03:01
0

Java garbage collection doesn't work by reference counting. It works by examining objects for reachability.

user207421
  • 305,947
  • 44
  • 307
  • 483