【问题标题】:What is a de-reflection optimization in HotSpot JIT and how does it implemented?什么是 HotSpot JIT 中的去反射优化,它是如何实现的?
【发布时间】:2015-05-01 19:41:50
【问题描述】:
观看 Towards a Universal VM 的演示文稿,我研究了这张幻灯片,其中列出了 HotSpot JIT 所做的所有优化:
在language-specific techniques 部分有一个去反射。我试图在互联网上找到一些关于它的信息,但失败了。我知道这种优化以某种方式消除了反射成本,但我对细节感兴趣。有人可以澄清一下,或者提供一些有用的链接吗?
【问题讨论】:
标签:
java
optimization
jvm
jit
jvm-hotspot
【解决方案1】:
是的,有一个优化可以降低反射成本,尽管它主要在类库中实现,而不是在 JVM 中。
在 Java 1.4 之前,Method.invoke 通过对 VM 运行时的 JNI 调用来工作。每次调用都需要至少两次从 Java 到 Native 再到 Java 的转换。 VM 运行时解析方法签名,验证传递的参数类型是否正确,执行装箱/拆箱并为调用的方法构造一个新的 Java 框架。这一切都相当缓慢。
由于 Java 1.4 Method.invoke 使用动态字节码生成如果方法被调用超过 15 次(可通过 sun.reflect.inflationThreshold 系统属性配置)。负责调用给定特定方法的特殊 Java 类是在运行时构建的。这个类实现了sun.reflect.MethodAccessor java.lang.reflect.Method 委托调用的sun.reflect.MethodAccessor。
动态字节码生成的方法要快得多,因为它
- 不受 JNI 开销的影响;
- 不需要每次都解析方法签名,因为通过Reflection调用的每个方法都有自己唯一的MethodAccessor;
- 可以进一步优化,例如这些 MethodAccessor 可以受益于所有常规 JIT 优化,例如内联、常量传播、自动装箱消除等。
请注意,此优化主要在Java code 中实现,无需 JVM 协助。 HotSpot VM 使这种优化成为可能的唯一一件事是跳过对此类生成的 MethodAccessors 的字节码验证。否则验证者将不允许,例如,调用私有方法。