1.2 平台版本约定

本书基于 Oracle HotSpot JVM 和 Java Standard Edition(Java SE)7 和 8。在发布版之间,Oracle 更新会定期发布更新版本。多数时候,更新版本只修订 bug,不会加入语言新特性或者变更关键功能,但会更改调优标志的默认值。Oracle 很可能将在本书出版之后提供更新版本,当前版本为 Java 7 update 40 和 Java 8(迄今为止,还没有 Java 8 的更新版本)1。如果更新版本对 JVM 的行为做了重大修订,则会命名如下:7u6(Java 7 update 6)。

1现在为 Java 7 update 55,Java 8 update 5。——译者注

本书关于 Java 企业版(Java EE)的内容是基于 Java EE 7。

虽然当前版本的 Java 构建于之前的发布版,但本书并不涉及老版本 Java 的性能调优。对这本讲述性能调优的书而言,Java 7 是一个很好的起始点,因为 Java 7 引入了大量的性能新特性和优化。其中最主要的是称为 G1 的垃圾收集(GC)算法(老版本的 Java 包含了 G1 的试验版,但直至 Java 7u4,G1 才真正可用于生产环境)。Java 7 也包括许多与性能相关的新特性和增强,可以让我们更清楚地了解 Java 应用的运转。Java 8 再接再厉,平台得到了进一步增强(例如引入了 lambda 表达式)。Java 8 自身的性能得到了巨大提升,在好几个关键性领域都大大超过了 Java 7。

JVM 还有其他实现。Oracle 自己的 JRockit JVM(支持 Java SE 6)。IBM 提供了自己的Java 兼容实现(包括 Java 7 版本)。还有许多其他公司得到许可从而可以改进 Oracle 的 Java 技术。

Oracle 的商业版 JVM

Java 和 JVM 都是开源的,任何想参与 Java 开发的人都可以加入项目:http://openjdk.java.net。即便你不打算参与开发,也可以从上述网站免费下载源代码。本书讨论的所有内容基本上都是基于开源版的 Java。

Oracle 也有商业版的 Java,可以通过支持合同获得。它基于标准开源版本的 Java 平台,但包括了一些开源版中所没有的特性。商业版 JVM 中和性能密切相关的一个特性就是 Java 飞行记录器(Java Flight Recorder,JFR,参见 3.4.1 节)。

除非特别说明,本书所有的内容都适用于开源版的 Java。

虽然只有通过兼容性测试的平台才能使用 Java 的名称,但本书不会总是围绕兼容性展开讨论。那些调优标志尤其如此。所有的 JVM 实现都有一个或多个垃圾收集器,但每个供应商所提供的 GC 实现,其调优标志都是产品特定的。所以本书所讲的概念可适用于所有 Java 实现,但具体的调优标志和建议仅适用于 Oracle 的标准(基于 HotSpot 的)JVM。

用较早版本的 HotSpot JVM 时要注意,标志及其默认值在发布版之间可能会发生变化。本书只涵盖 Java 7(直到 7u40)和 Java 8(仅首个版本),而不是试图穷尽迄今为止的各个版本。以后的版本(例如,假定是 7u60)可能会对这些信息做少许改动。重要的变更请查阅发布说明。

从 API 层面来看,不同 JVM 实现之间的兼容性很高,即便特定类在 Oracle HotSpot Java SE(或 EE)和其他平台上的实现方式也有细微的不同。类的功能必须等价,但具体实现可以变更。所幸这些并不多见,不会对性能产生重大影响。

对于本书的剩余部分,术语 Java 和 JVM 应理解为特指 Oracle HotSpot 的实现。严格来说,“JVM 首次执行时不会进行代码编译”的说法并不正确,因为有些 Java 的实现在首次执行时会编译代码。但这种略写比到处写(和读)“Oracle HotSpot JVM……”要简便得多。

JVM调优标志

除了少数例外,JVM 主要接受两类标志:布尔标志和附带参数的标志。

布尔标志采用以下语法:-XX:+FlagName 表示开启,-XX:-FlagName 表示关闭。

附带参数的标志采用以下语法:-XX:FlagName=something,表示将标志 flagName 的值设置为 something。其中 something 通常可以为任意值。例如 -XX:NewRatio=N,表示 NewRatio 可以设置为任意值 NN 是我们讨论所关注的重点)。

介绍每个标志时,我们会讨论它的默认值。默认值的选取通常综合考虑了不同因素:运行 JVM 的物理平台,以及其他传给 JVM 的命令行参数。如有疑问,可以参考 3.2.1 节所介绍的方法,在给定的命令行上,添加 -XX:+PrintFlagsFinal(默认为 false,即“关闭”)就能获得具体运行环境中特定标志的默认值。基于环境对标志进行自动调优的过程称为自动优化(Ergonomics)。

Client 和 Server 类虚拟机

Java 的自动优化前提是机器被分为“Client”和“Server”。这两个术语直接与特定平台(参见第 4 章)上的默认 JVM 编译器相关,它们也设定了默认的调优标志。例如,机器类别决定了平台默认的垃圾收集器(参见第 5 章)。

Microsoft Windows 上运行的任何 32 位 JVM(无论机器上 CPU 的个数是多少),以及单 CPU 机器(不论是什么操作系统)上运行的任何 32 位 JVM,都是 Client 类机器。所有其他机器(包括所有 64 位 JVM)都被认为是 Server 类。

从 Oracle 和 OpenJDK 站点下载的 JVM,被称为“产品”JVM。需要生成不同版本的 JVM 时,可以从源代码构建:调试版、开发版等。这些版本通常有更多的特性。特别是开发版,包含了大量的调优标志,开发人员可以尝试与 JVM 各种算法的细节打交道。不过本书基本上不会考虑这些标志。