Cost of using final fields

2020-06-08 09:20发布

问题:

We know that making fields final is usually a good idea as we gain thread-safety and immutability which makes the code easier to reason about. I'm curious if there's an associated performance cost.

The Java Memory Model guarantees this final Field Semantics:

A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields.

This means that for a class like this

class X {
    X(int a) {
        this.a = a;
    }
    final int a;

    static X instance;
}   

whenever Thread 1 creates an instance like this

X.instance = new X(43);
while (true) doSomethingEventuallyEvictingCache();

and Thread 2 sees it

 while (X.instance == null) {
      doSomethingEventuallyEvictingCache();
 }
 System.out.println(X.instance.a);

it must print 43. Without the final modifier, the JIT or the CPU could reorder the stores (first store X.instance and then set a=43) and Thread 2 could see the default-initialized value and print 0 instead.

When JIT sees final it obviously refrains from reordering. But it also has to force the CPU to obey the order. Is there an associated performance penalty?

回答1:

Is there an associated performance penalty?

If you take a look at the source code of the JIT compiler, you will find the following comment regarding final member variables in the file src/share/vm/opto/parse1.cpp:

This method (which must be a constructor by the rules of Java) wrote a final. The effects of all initializations must be committed to memory before any code after the constructor publishes the reference to the newly constructor object. Rather than wait for the publication, we simply block the writes here. Rather than put a barrier on only those writes which are required to complete, we force all writes to complete.

The compiler emits additional instructions if there are final member variables. Most likely, these additional instructions cause a performance penalty. But it's unclear, if this impact is significant for any application.