Hi Aleksey I happened to see the performance to access a field by VarHandle API is much worse than the native access.
I tested the following situations: 1. reading a volatile field directly 2. calling getVolatile against this volatile field 3. calling getVolatile against another non-volatile field As my expectation, Situation 2 has similar performance with situation 3, but both of them have 100 times of situation 1 execution time in my test. I think it should be due to some overhead, and it doesn't violate the JEP 193 performance requirement. But I still can't figure out why it's so slow after runtime compiling? Hope you can give me some point. Thanks! My test code is as below: import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; public class Test5 { static final int iter_num = 100000000; private volatile int vf = 1; private int f = 1; final VarHandle vhf; final VarHandle vhvf; final ThreadMXBean threadMXBean; public Test5 () throws Exception { vhf = MethodHandles.lookup().findVarHandle( Test5.class, "f", int.class); vhvf = MethodHandles.lookup().findVarHandle( Test5.class, "vf", int.class); threadMXBean = ManagementFactory.getThreadMXBean(); //System.out.println(threadMXBean.isCurrentThreadCpuTimeSupported()); //System.out.println(threadMXBean.isThreadCpuTimeEnabled()); } public void measGetVolatileField() { int tmpProgress = 0; long startCpu = threadMXBean.getCurrentThreadCpuTime(); long startUser = threadMXBean.getCurrentThreadUserTime(); for (int i = 0; i < iter_num; ++i) { tmpProgress += vf; } long endCpu = threadMXBean.getCurrentThreadCpuTime(); long endUser = threadMXBean.getCurrentThreadUserTime(); long durCpu = endCpu -startCpu; long durUser = endUser - startUser; System.out.println("measGetVolatileField"); System.out.println("cpu time: " + durCpu); System.out.println("user time: " + durUser); System.out.println(tmpProgress); } public void measGetVolatileFieldByVHWithVolatile() { int tmpProgress = 0; long startCpu = threadMXBean.getCurrentThreadCpuTime(); long startUser = threadMXBean.getCurrentThreadUserTime(); for (int i = 0; i < iter_num; ++i) { tmpProgress += (int) vhvf.getVolatile(this); } long endCpu = threadMXBean.getCurrentThreadCpuTime(); long endUser = threadMXBean.getCurrentThreadUserTime(); long durCpu = endCpu -startCpu; long durUser = endUser - startUser; System.out.println("measGetVolatileFieldByVHWithVolatile"); System.out.println("cpu time: " + durCpu); System.out.println("user time: " + durUser); System.out.println(tmpProgress); } public void measGetFieldByVHWithVolatile() { int tmpProgress = 0; long startCpu = threadMXBean.getCurrentThreadCpuTime(); long startUser = threadMXBean.getCurrentThreadUserTime(); for (int i = 0; i < iter_num; ++i) { tmpProgress += (int) vhf.getVolatile(this); } long endCpu = threadMXBean.getCurrentThreadCpuTime(); long endUser = threadMXBean.getCurrentThreadUserTime(); long durCpu = endCpu -startCpu; long durUser = endUser - startUser; System.out.println("measGetFieldByVHWithVolatile"); System.out.println("cpu time: " + durCpu); System.out.println("user time: " + durUser); System.out.println(tmpProgress); } public static void main(String[] args) throws Exception { for (int i = 0; i < 5; i++) { Test5 test = new Test5 (); Thread threadA = new Thread(() -> test.measGetVolatileField()); Thread threadB = new Thread(() -> test.measGetVolatileFieldByVHWithVolatile()); Thread threadC = new Thread(() -> test.measGetFieldByVHWithVolatile()); threadA.start(); threadA.join(); threadB.start(); threadB.join(); threadC.start(); threadC.join(); } } }