你知道 JVM 怎么优化反射的么?

393 阅读1分钟

优化原理

Java中如果对一个方法采用反射的方式进行调用,一旦这个方法调用的次数达到阈值,这个时候JVM会自动对该调用进行优化,内部会自动转换为对某个类或者实例方法的调用来提高效率。

graph TD
Method.invoke --> 
DelegatingMethodAccessorImpl.invoke -->
NativeMethodAccessorImpl.invoke

代码调用链

通过Method对象调用invoke方法: image.png 然后调用到DelegatingMethodAccessorImplinvoke方法,该类是一个代理模式,实际上会调用到NativeMethodAccessorImplinvoke方法: image.png

image.png

image.png NativeMethodAccessorImplinvoke方法中会对当前调用方法的次数进行判断,如果达到了阈值(默认是15)时,就会动态生成一个类,并将设置为DelegatingMethodAccessorImpl类的代理对象,从而方法的实际调用就会变为调用这个动态类的invoke方法: image.png

image.png

image.png

image.png 通过Arthasjad命令反编译类可以看到这个动态生成的类的invoke方法的实现,可以看到invoke的方法里面没有再去调用本地方法了,而是相当于直接调用类的静态方法: image.png

控制参数

Java中如果调用反射方法的次数过多,Java中会自动把反射方法的调用优化为自动调用生成的动态类。Java中通过几个JVM属性来控制。 sun.reflect.noInflation 用来控制是否直接生成动态类;

image.png sun.reflect.inflationThreshold 用来控制生成动态类的阈值,默认值为15;

image.png

在Idea中可以通过以下方式设置JVM属性:

image.png