优化原理
Java中如果对一个方法采用反射的方式进行调用,一旦这个方法调用的次数达到阈值,这个时候JVM会自动对该调用进行优化,内部会自动转换为对某个类或者实例方法的调用来提高效率。
graph TD
Method.invoke -->
DelegatingMethodAccessorImpl.invoke -->
NativeMethodAccessorImpl.invoke
代码调用链
通过Method对象调用invoke方法:
然后调用到
DelegatingMethodAccessorImpl的invoke方法,该类是一个代理模式,实际上会调用到NativeMethodAccessorImpl的invoke方法:
NativeMethodAccessorImpl的invoke方法中会对当前调用方法的次数进行判断,如果达到了阈值(默认是15)时,就会动态生成一个类,并将设置为DelegatingMethodAccessorImpl类的代理对象,从而方法的实际调用就会变为调用这个动态类的invoke方法:
通过
Arthas的jad命令反编译类可以看到这个动态生成的类的invoke方法的实现,可以看到invoke的方法里面没有再去调用本地方法了,而是相当于直接调用类的静态方法:
控制参数
Java中如果调用反射方法的次数过多,Java中会自动把反射方法的调用优化为自动调用生成的动态类。Java中通过几个JVM属性来控制。 sun.reflect.noInflation 用来控制是否直接生成动态类;
sun.reflect.inflationThreshold 用来控制生成动态类的阈值,默认值为15;
在Idea中可以通过以下方式设置JVM属性: