1.反射调用过程中会产生大量的临时对象,这些对象会占用内存,可能会导致频繁 gc,从而影响性能。
2.反射调用方法时会从方法数组中遍历查找,并且会检查可见性等操作会耗时。
3.反射在达到一定次数时,会动态编写字节码并加载到内存中,这个字节码没有经过编译器优化,也不能享受JIT优化。
4.Method#invoke 方法会对参数做封装和解封操作,会涉及自动装箱/拆箱和类型转换,都会带来一定的资源开销。
5.反射方法难以内联
6.需要检查方法可见性和校验参数
invoke 方法的参数是一个可变长参数,也就是构建一个 Object 数组存参数,这也同时带来了基本数据类型的装箱操作,在 invoke 内部会进行运行时权限检查,这也是一个损耗点。普通方法调用可能有一系列优化手段,比如方法内联、逃逸分析,而这又是反射调用所不能做的,性能差距再一次被放大。
优化反射调用,可以尽量避免反射调用虚方法、关闭运行时权限检查、可能需要增大基本数据类型对应的包装类缓存、如果调用次数可知可以关闭 Inflation 机制,以及增加内联缓存记录的类型数目。
网友评论