关于Java反射的性能问题及其常见的处理方法

调用Java的反射API是有较高的性能开销的,这方面的性能比较文章较多,在此不赘述。

[color=blue][size=xx-large]原因[/size][/color]
纠其原因,性能的开销主要在两方面:
[color=blue][size=large]1.产生了Dynamic Resolve[/size][/color]
无论是通过字符串获取Class、Method还是Field,都需要JVM的动态链接机制动态的进行解析和匹配,势必造成性能开销。

[color=blue][size=large]2.安全性验证[/size][/color]
每一次的反射调用都会造成Java安全机制进行额外的安全性验证,造成性能开销。

[color=blue][size=large]3.影响运行时优化[/size][/color]
反射代码使得许多JVM的运行时优化无法进行。


[color=blue][size=xx-large]处理方法[/size][/color]
针对此,常见的处理方法主要有以下几种:

[color=blue][size=large]1.使用Cache[/size][/color]
针对上述[b][i]原因1[/i][/b]: 对通过反射调用获得的Class、Method、Field实例进行缓存,避免多次Dynamic Resolve。


[color=blue][size=large]2.使用MethodHandle类[/size][/color]
针对上述[b][i]原因2[/i][/b]:Java 7开始提供了java.lang.invoke.MethodHandle类,MethodHandle类的安全性验证在获取实例时进行而不是每次调用时都要进行验证,减小开销。

[color=blue][size=large]3.使用Runtime创建的类[/size][/color]
该方法最为强大,可以针对上述[b][i]原因1、2、3[/i][/b]进行全面优化。具体做法为:
[list]
[*]在编译时设计好一个接口,由该接口封装所有的反射调用。
[*]在运行时动态生成一个类实现该接口,该动态生成的类一旦完成define就和普通类没有区别,不需要后续的Dynamic Resolve,没有额外的安全性验证,也不会影响JVM的运行时优化。
[/list]
该方法不能覆盖反射API的所有Use case,例如某个反射调用需要修改某实例的private字段,是无法动态生成一个合法的类这样去做的。

关于具体如何动态生成符合条件的类可以参考[url=http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/]Javassit[/url],本质上还是用到了Classloader截获技术,这种技术是有限制的,例如在安全性级别较高的Applet运行环境中就有很多使用限制。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值