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

ProGuard主页列为一项function:

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

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

这很重要吗?

它是否会影响multithreading通过默认类加载器的同步方面导致的减速?

正如ProGuard 常见问题解答提示 :

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

查看按类型检查的Java虚拟机规范 validation部分:

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

这意味着Java虚拟机实现不能选择在一次情况下而不是在另一种情况下求助于类型推断。 它必须拒绝不通过类型检查validation的类文件,或者每当类型检查失败时始终故障转移到类型推理validation器。

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

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

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

来自维基百科的类型推断 :

类型推断是在编译时自动推断表达式类型的能力。 […]

为了获得推断表达式类型所需的信息,编译器要么将这些信息收集为聚合,然后减少为其子表达式给出的类型注释,要么通过隐含地理解各种primefaces值的类型[… ]。

OpenJDK HotSport运行时概述很好地解释了它:

目前有两种分析字节码的方法,以确定每条指令将出现的操作数的类型和数量。 传统方法称为“类型推断”,通过对每个字节码执行抽象解释并在分支目标或exception句柄处合并类型状态来进行操作。 分析迭代字节码,直到找到类型的稳定状态。 如果找不到稳定状态,或者结果类型违反某些字节码约束,则抛出VerifyError。 […]

JDK6中的新function是第二种validation方法,称为“类型validation”。 在此方法中,Java编译器通过代码属性StackMapTable为每个分支或exception目标提供稳态类型信息。 StackMapTable由许多堆栈映射帧组成,每个堆栈映射帧指示表达式堆栈上的项目类型以及方法中某些偏移量的局部变量。 然后,JVM只需要执行一次字节码传递,以validation类型的正确性,以validation字节码。 […]

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

根据这篇Java 6白皮书的改进是:

Java虚拟机的引导和扩展类加载器已得到增强,可以改善Java应用程序的冷启动时间。 在Java SE 6之前,打开系统jar文件导致Java虚拟机读取一个1兆字节的ZIP索引文件,当文件不在磁盘缓存中时,该文件转换为大量磁盘搜索活动。 启用“类数据共享”后,Java虚拟机现在提供了一个“元索引”文件(位于jre / lib中),其中包含有关哪些包(或包前缀)包含在哪些jar文件中的高级信息。

这有助于JVM在加载Java应用程序类时避免打开引导和扩展类路径上的所有jar文件。

这种特殊的改进不应该对运行程序产生任何影响,因为系统jar中的类已经被加载了。 它只会影响应用程序的第一次启动时间。

(回答我自己的问题)

我在ProGuard网站的“ 什么是预validation? ”部分找到了大部分答案:

加载类文件时,类加载器会对字节代码执行一些复杂的validation。 此分析可确保代码不会意外或故意从虚拟机的沙箱中分离出来。 […] Java 6引入了拆分validation。 […] Java 6编译器将预validation信息添加到类文件([…] StackMapTable属性),以简化类加载器的实际validation步骤。 然后可以更快地以更节省内存的方式加载类文件。

这似乎与并发性无关。

所以剩下的一个问题是:“ 它有意义吗? ”,在很大程度上回答“否”:

在1.6 VM上运行“-target 1.5”生成的Java类文件的性能影响?