Final member variables makes for better GC?
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 le开发者_如何学编程ft, 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)?
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.)
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
Java garbage collection doesn't work by reference counting. It works by examining objects for reachability.
精彩评论