JIT优化防止技术

时间:2017-02-07 18:39:27

标签: java optimization java-8 jit

java-8来源中,我们可以在类Class中找到相当棘手的JIT优化方法:

/*
 * Private constructor. Only the Java Virtual Machine creates Class objects.
 * This constructor is not used and prevents the default constructor being
 * generated.
 */
private Class(ClassLoader loader) {
    // Initialize final field for classLoader.  The initialization value of non-null
    // prevents future JIT optimizations from assuming this final field is null.
    classLoader = loader;
}

因此,永远不会调用此构造函数,但JIT将被此欺骗“欺骗”。

我的问题是:它可以用稍微不同的方式实现,比如说

private Class() {
    classLoader = (ClassLoader)(new Object());
}

这绝对是毫无意义的逻辑,但是如果永远不会调用构造函数那么重要吗?

此类技巧是否会阻止JIT进行此优化?

2 个答案:

答案 0 :(得分:5)

在Java 6和Java 7(以及更新40之前的Java 8)中,构造函数与private Class() {}一样简单,但在这些版本中,也没有classLoader字段。

这意味着ClassClassLoader之间的关联必须以特定的JVM特定方式维护,因此,getClassLoader()必须调用native方法,不一定涉及JNI,而是作为JVM内部操作处理,但仍需要特别注意JVM的本机代码。此外,垃圾收集者必须知道这种特殊的关系。

相比之下,在Reflection中隐藏字段并不复杂,而现在有一个普通字段简化了JVM的本机代码,最明显的是getClassLoader()操作和垃圾收集器实现。如果优化器是普通字段,则内联访问也可能更简单。

现在,当Class对象是通过特殊的JVM代码创建的,而不是使用声明的构造函数时,它可能与优化JIT的假设相矛盾,这些假设是通过分析构造函数的实际代码来预测此{{1}的可能值。 }} field。

请注意,没有人说当前的JIT是那么聪明。该评论讨论了假设的“未来的JIT优化”。使用参数值初始化字段的构造函数与JVM实际执行的操作一致。

相反,像您建议的final这样的构造函数可能会导致假设的优化器得出结论,该字段无法使用实际的classLoader = (ClassLoader)(new Object());实例进行初始化,因为该代码永远无法正常完成。

答案 1 :(得分:0)

Class来源中的评论指出,初始化值使未来的JIT优化知道classLoader字段不为空。因此优化器可能会做一个均匀的将来会有更好的工作。

要阻止优化,只需声明您的字段volatile