使用实时 Java 进行开发,第 2 部分: 改善服务质量
2009-11-02 00:00:00 来源:WEB开发网JVM 中的第三个延迟来源是 JIT 编译器。在应用程序运行时,它将程序的方法从 javac 生成的字节码翻译为运行应用程序的 CPU 的本机指令。JIT 编译器是 Java 平台取得成功的基础,因为它实现了很高的应用程序性能,而且没有牺牲 Java 字节码的平台独立性。在过去 10 多年中,JIT 编译器工程师一直在尽力改善 Java 应用程序的吞吐量和延迟。
不幸的是,这类改进带来了 Java 应用程序性能的暂停,因为 JIT 编译器从应用程序 “偷取” 了一些周期来为特定方法生成已编译(或要重新编译)的代码。取决于被编译方法的大小和 JIT 选择编译它的积极程度,编译时间可能小于 1 微妙,也可能大于 1 秒(对于 JIT 编译器发现的非常大的方法,这类方法会占用应用程序的大量执行时间)。但是 JIT 编译器本身的行为并不是应用程序计时中的意外偏差的唯一来源。因为 JIT 编译器工程师将绝大部分精力都用在平均性能上,以最有效地改进吞吐量和延迟性能,所以 JIT 编译器通常执行多种优化,这些优化 “通常” 是正确的或 “在大部分情况下” 具有很高的性能。一般而言,这些优化非常有效,并且开发了启发方法来使优化很好地符合最常见的应用程序运行场景。但是,在一些情形下,这类优化可能带来严重的性能易变性。
除了预加载所有类,还可以请求 JIT 编译器在应用程序初始化期间显式编译这些类的方法。清单 4 扩展了 清单 2 中的类预加载代码,以控制方法编译:
清单 4. 受控的方法编译
Iterator<String> classIt = listOfClassNamesToLoad.iterator();
while (classIt.hasNext()) {
String className = classIt.next();
try {
Class clazz = Class.forName(className);
String n = clazz.name();
java.lang.Compiler.compileClass(clazz);
} catch (Exception e) {
System.err.println("Could not load class: " + className);
System.err.println(e);
}
}
java.lang.Compiler.disable(); // optional
更多精彩
赞助商链接