Java 6类加载的速度有多快?

Ed *_*aub 8 java performance jvm classloader

ProGuard的主页上列出的功能:

  • 重新定位和预验证Java 6的现有类文件,以充分利用Java 6的更快的类加载.

这涉及到Java 6的不同之处是什么?

这很重要吗?

它是否会影响多线程通过默认类加载器的同步方面引起的减速?

Dan*_*ruz 2

正如ProGuard 常见问题解答所提示的那样:

\n\n
\n

Java 6编译器将预验证信息添加到类文件中

\n
\n\n

查看Java 虚拟机规范 通过类型检查进行验证部分:

\n\n
\n

如果 Java 虚拟机实现尝试通过类型推断对版本 50.0 类文件执行验证,则在类型检查验证失败的所有情况下,它都必须执行此操作。

\n\n

这意味着 Java 虚拟机实现不能选择在一次情况下诉诸类型推断,而在另一种情况下则不诉诸类型推断。它必须要么拒绝未通过类型检查进行验证的类文件,要么在类型检查失败时一致故障转移到类型推断验证程序。

\n\n

类型检查器需要具有 Code 属性的每个方法的堆栈映射框架列表。类型检查器读取每个此类方法的堆栈映射帧,并使用这些映射生成 Code 属性中指令的类型安全性证明。

\n
\n\n

从 Java 6、类文件 50.0 及更高版本开始,JVM 可以在类文件验证期间使用类型检查或类型推断。在尝试了解性能优势之前,先了解什么是类型检查和类型推断?本文《面向对象编程语言的类型检查和类型推断》指出:

\n\n
\n

类型系统是编程语言的重要组成部分。完全依赖运行时类型检查的语言提供了高度的灵活性,但通常必须牺牲性能才能做到这一点。

\n
\n\n

来自维基百科关于类型推断的内容:

\n\n
\n

类型推断是在编译时自动部分或全部推断表达式类型的能力。[...]

\n\n

为了获取推断表达式类型所需的信息,编译器要么将此信息收集为为其子表达式给出的类型注释的聚合和后续减少,要么通过对各种原子值的类型的隐式理解[... ]。

\n
\n\n

OpenJDK HotSport 运行时概述很好地解释了这一点:

\n\n
\n

目前有两种方法可以分析字节码以确定每条指令将出现的操作数的类型和数量。传统方法称为\xe2\x80\x9ctype inference\xe2\x80\x9d,通过对每个字节码执行抽象解释并在分支目标或异常句柄处合并类型状态来进行操作。分析会迭代字节码,直到找到类型的稳定状态。如果找不到稳定状态,或者结果类型违反了某些字节码约束,则会引发VerifyError。[...]

\n\n

JDK6 中新增了第二种验证方法,称为 \xe2\x80\x9ctype Verification\xe2\x80\x9d。在此方法中,Java 编译器通过代码属性 StackMapTable 为每个分支或异常目标提供稳态类型信息。StackMapTable 由许多堆栈映射帧组成,每个堆栈映射帧指示表达式堆栈上以及方法中某个偏移处的局部变量中的项的类型。然后,JVM 只需要对字节码执行一次传递即可验证类型的正确性,从而验证字节码。[...]

\n
\n\n

类型检查意味着 JVM 可以一次性遍历类文件来验证类型系统;类型推断需要多次传递。这是显着的性能节省吗?它可能与应用程序中的类总数以及小于 50.0 (Java 6) 和 50.0 及以上的类文件数量有关。如果您的应用程序不是性能关键型应用程序,我不会担心;如果是,那么您可以运行一些基准测试来比较将应用程序编译为 Java 5 和 Java 6 类文件时的性能差异。

\n