Final static and final non-static fields and JVM optimization

I'm curious how static final fields are handled by the JVM. I saw a similar question here , but that is not what I am looking for. Consider this example:

 public class TestClassX { public final int CODE_A = 132; public final int CODE_B = 948; public final int CODE_C = 288; // some other code } public class TestClassY { public static final int CODE_A = 132; public static final int CODE_B = 948; public static final int CODE_C = 288; // some other code } 

In TestClassX fields, since they are final and cannot be changed, have the same values ​​in all instances of the TestClassX class. Of course, I can not write TestClassX.CODE_A , but I can say that these values ​​are actually common for all instances - I am sure that each instance has a CODE_A field with a value of 132 .

In TestClassY I can use the syntax TestClassY.CODE_A , but at first glance it is only easier for the developer who sees "Oh, these values ​​are common to all instances."

My main question: I think that the JVM in the case of TestClassX does not use extra memory for final fields every time a new instance is created. Does it have? Is the JVM any kind of optimization in this case, and what kind of optimization is it?

Additional question 1) I am also sure that I am missing something very important here, which is the reason for my doubts. What is it?

Additional question 2) PPC. How can I take a look at what the Java source code looks like after optimizing the JVM (so that I can use it in the future;))? Does any IDE support this functionality? For example, IntelliJ? I would just like to see how the JVM handles my TestClassX and TestClassY .

+5
source share
2 answers
  • Non-static fields are always present in instances. They do not retain memory.
  • In general, the JVM does not optimize non-static fields. Even if they are final, they can still be set to a different value using reflection or during deserialization.
  • There is an experimental option VM -XX:+TrustFinalNonStaticFields (disabled by default), which tells the JVM to optimize access to such fields, i.e. consider them as constants and exclude field loads.
  • There is an option -XX:+PrintAssembly VM to compile JIT-compiled code.
+8
source

For the first part of your question, maybe this answer may help you.

In the second part, you can see the generated assembly (as indicated in this answer ) by adding the -XX:+PrintOptoAssembly when starting / compiling the code.

I should also add that the assembly code you provided is not the actual operation code generated by jvm, but the code that needs to be run under your actual architecture.

Hope this helps!

+1
source

All Articles