Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cost of using final fields

Tags:

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?

like image 806
maaartinus Avatar asked May 07 '14 20:05

maaartinus


People also ask

Is it good to use final in Java?

In Java, the final keyword can be used while declaring an entity. Using the final keyword means that the value can't be modified in the future. This entity can be - but is not limited to - a variable, a class or a method.

Does final keyword increase performance?

When we apply the final keyword to a class, then that class cannot be subclassed. When we apply it to a method, then that method cannot be overridden. There are no reported performance benefits of applying final to classes and methods.

What is a final field?

A final field cannot have its value changed. A final field must have an initial value assigned to it, and once set, the value cannot be changed again. A final field is often also declared static . A field declared static and final is also called a "constant".

Are final Fields inherited in Java?

The final keyword, when applied to fields of a Java class, has nothing to do with inheritance. Instead, it indicates that outside of the constructor, that field cannot be reassigned.


1 Answers

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.

like image 120
nosid Avatar answered Sep 21 '22 15:09

nosid