Java Solaris 加入Sun中国技术社区 我的社区 注册说明
 
JDK 6.0 API 中文版
 
 
 
 
Java API 文档中文版
Java SE 6 性能白皮书
 
By , 2/28/08  

Java™ Platform Performance Engineering
Sun Microsystems,Inc.

 

目录

 

1   简介


Java SE 6(Java Platform Standard Edition 6)的一个主要设计原则就是以性能缺陷为目标,通过当前最流行的一些 Java 基准测试以及与 Java 社区的紧密协作来确定对性能影响最大的增强关键领域,从而提高性能和可伸缩性。

本指南将概述 Java Standard Edition 6 中新增功能和可伸缩性改进,同时提供各种行业标准和内部开发的基准测试结果,以便演示这些性能改进的影响。

2  新增功能和性能增强


Java SE 6 引入了一些新的功能和性能增强,为平台中的许多领域都提供了性能改进。这些改进包括:同步性能优化、编译器性能优化、新的并行缩并垃圾收集器(Parallel Compaction Collector)、工效更高的并发低停顿垃圾收集器(Concurrent Low Pause Collector),以及应用程序的启动性能。

2.1   运行时性能改进


2.1.1 偏向锁


偏向锁(Biased Locking)是一个优化的类,它通过消除与 Java 语言同步原语相关的原子操作改进无竞争同步性能。这些优化依赖于属性,它们不仅是大多数无竞争的监视器,而且在它们的生命期内最多被一个线程锁定。

对象通过监视器输入字节码或同步方法调用,“偏向”于第一个获取监视器的线程;随后与监视器相关的操作可以通过该线程执行而不需使用原子操作,从而获得更好的性能,特别在多处理器机器上,这种性能改进尤为明显。

由多线程而不是单线程对“偏向”对象的锁定尝试,将引起相对较大的操作开销,由此偏向被撤销。消除原子操作的好处必需超过锁定撤销惩罚从而使该优化有利可图。

使用大量无竞争的同步将获得显著的速度提升,而其他使用某些锁定模式的应用程序运行可能缓慢。

偏向锁在 Java SE 6 以及未来版本中将被默认启用。要禁用偏向锁,请向命令行添加 -XX:-UseBiasedLocking。

要了解关于偏向锁的更多详细信息,请参阅由 Kenneth Russell 和 David Detlefs 撰写的《ACM OOPSLA 2006》文章:“使用偏向锁和批量重新偏向(Bulk Rebiasing)消除与同步相关的原子操作”

2.1.2  锁粗化


Java SE 6 有一些锁定模式。在这些模式下锁被释放,然后在一段代码内被重新获得,在此之间没有可观察的操作出现。在那样的情况下,在 hotspot 中实施的锁粗化优化技术消除了加锁和解锁的操作(当一个锁被释放时,在解锁与下次加锁之间又没有意义的事情可干,那么可以重新获得该锁)。通过扩大现存同步区域基本上减少了同步工作的总量。围绕一个循环执行此操作可能导致一个锁被长期持有,因此锁粗化技术只在非循环的控制流上使用。

该功能默认使用。要禁用此功能,请向命令行添加下列选项:-XX:-EliminateLocks

2.1.3  自适应自旋


自适应自旋是一项优化技术。在该优化技术中,两阶段自旋再阻塞(spin-then-block)策略被尝试竞争同步输入操作的多线程使用。该技术启用多线程以避免对性能产生不合需要的影响,例如翻译后援缓存器 (Translation Lookaside Buffers,TLB)的上下文切换和重新存入。该性能是“自适应的”,因为自旋持续时间由策略决策确定,基于以下因素:在相同监视器上的自旋尝试成功率和/ 或最新自选尝试失败率,以及最新锁的所有者状态。

要了解自适应自旋的更多信息,请参阅 Dave Dice 的演示文稿:"Java SE 6 中的同步"

在 x86 和 amd64 平台上支持大页面堆


在 x86 和 amd64 平台上 Java SE 6 支持大内存页面堆。大内存页面堆(Large page heap)帮助操作系统避免开销巨大的翻译后援缓存器(Translation-Lookaside Buffer,TLB)错失,从而使内存密集型应用程序更好地运行(单个 TLB 就可以代表较大的内存范围)。

请注意大页面内存有时可以对系统性能产生负面影响。例如,当大量内存被一个应用程序固定,可能会产生常规内存不足,并引起其它应用程序中过度地分页,从而使整个系统运行缓慢。还请注意,对于一个已经启动很长时间的系统,过多的碎片使得系统不能保留大页面内存。当这种情况发生时,操作系统可能转而采用常规页面。而且,可以通过设置 -Xms == -Xmx、 -XX:PermSize == -XX:MaxPermSize -XX:InitialCodeCacheSize == -XX:ReserverCodeCacheSize 最小化这种影响。

大页面的另一个可能的缺陷是,永久保存区域和代码缓存的默认页面大小可能因为使用大页面而更大;当页面大小比这些内存区域的默认页面大小大时这方面的问题就要特别值得注意。

在 Solaris 操作系统上默认启用对大页面的支持。在 Windows 和 Linux 操作系统上默认关闭对大页面的支持。请向命令行添加 -XX:+UseLargePages 以便启用该功能。请注意,操作系统配置更改可能要求启用大页面。要了解更多信息,请参阅 Sun Developer Network 上的 关于 Java 对大内存页的支持 文档


2.1.5 数组复制性能改进


方法指令 System.arraycopy() 在 Java SE 6 中得到进一步增强。当没有出现重叠时,手工编码程序集存根用于每种页面类型大小。

2.1.6 HotSpot™ 客户机编译器中的后台编译。


在 Java SE 6 之前,HotSpot 客户机(HotSpot Client)编译器在后台中不能默认编译 Java 方法。结果,超线程(Hyperthreaded)或多进程(Multi-processing)系统不能利用多余的 CPU 周期来优化 Java 代码的执行速度。目前,在 Java SE 6 HotSpot 客户机编译器中启用了后台编译。

2.1.7 针对 HotSpot™ 客户机编译器的线性扫描寄存器分配算法


HotSpot 客户编译器公开了一种新的线性扫描寄存器分配算法。该算法依赖于静态单一分配(Static Single Assignment,SSA)形式。这一做法的另外好处是提供一个简化了的数据流分析和较短的动态时间间隔,这样取得了在编译时间和程序运行时之间产生较好的折衷。这种新的算法已经在许多内部基准和符合行业标准基准上提供了大约 10% 的性能改进。

要了解关于这个新功能的详细信息,请参阅以下文章:针对 Java HotSpot™ 客户机编译器的线性扫描寄存器分配

2.2 垃圾收集

2.2.1 并行缩并垃圾收集器


并行缩并是一种功能,它启用并行垃圾收集器来以并行方式执行主要收集操作,从而导致较低的垃圾收集开销和更好的应用程序执行能力,对于带有大内存堆的应用程序效果特别明显。该垃圾收集器最适合具有两个或多个处理器或硬件线程的平台。

在 Java SE 6 之前,年轻代以并行方式收集垃圾,主要收集操作使用单线程执行。对于经常执行大的收集(major collection)操作的应用程序来说,这将对可伸缩性产生不利影响。

在 JDK 6 中默认使用并行缩并,但是可以通过向 JDK 5 更新 6 以及未来版本中的命令行添加 -XX:+UseParallelOldGC 禁用它。

请注意,并行缩并在与并发标记清除(mark-sweep)收集器结合使用时不可用;它只能和并行年轻代收集器(-XX:+UseParallelGC)一起使用。下列参考文档提供了可用收集器和使用建议的更多详细内容。

关于并行缩并收集(Parallel Compaction Collection)的更多详细信息,请参阅 Java SE 6 发行说明 。有关垃圾收集的更多信息,HotSpot 内存管理白皮书 描述了在 HotSpot 中的各种可用收集器、何时使用并行缩并,以及算法的高层描述方面的建议。

2.2.2 并发低停顿垃圾收集器:并发标记清除收集器增强


并发标记清除收集器性能已经得到了增强以便为 System.gc() 和 Runtime.getRuntime().gc() 方法指令提供并发收集。在 Java SE 6 之前,为了收集整个堆,这些方法停止所有应用程序线程,这样有时会导致在使用大内存堆的应用程序中很长时间的停顿。结合并发标记清除收集器所实现的目标,这个新功能将使收集器在整个堆收集期间保持尽可能短时间的停顿。

要启用该功能,向 Java 命令行添加 -XX:+ExplicitGCInvokesConcurrent 选项。

在并发标记清除(CMS)收集器中,并发加标记的任务现在在多处理器平台上以并行的方式执行。这显著地减少了并发加标记周期的持续时间,并使得收集器更好地支持带有较多线程的应用程序,从而获得很高的对象分配率。在大型多处理器机器上此种性能改进效果尤为突出。

关于这些新功能的更多详细信息,请参阅 Java SE 6 发行说明

2.3 Java Virtual Machine 6.0 中的工效特性

 


在 Java SE 5 中,引入了与平台有关的垃圾收集器的默认选择、堆大小和运行时编译器,以便当要求较少的命令行调优时更好地满足不同类型的应用程序需求。其中还引入了新的调优标志,以便使用户指定需要的行为来依次启用垃圾收集器,动态地调整堆的大小,直至满足指定行为。在 Java SE 6 中,默认选择性能已经得到进一步增强,改进了应用程序运行时性能并提高了垃圾收集器效率。

下列图表对比了 Java SE 5 和 Java SE 6 Update 2 之间即开即用 SPECjbb2005™ 的性能。在 Sun Fire V890 上使用 24 x 1.5 GHz UltraSparc CPU 和 64 GB RAM 运行 Solaris 10 进行此项测试:

[specjbb.png]

在每种情况下基准都不使用任何性能标志而运行。请参看 SPECjbb 2005 基准披露

下列图表对比了Java SE 5 和 Java SE 6 Update 2 之间的 I/O 性能。在
Sun Fire V890 上使用 24 x 1.5 GHz UltraSparc CPU 和 64 GB RAM 运行 Solaris 10 进行此项测试:

[specjbb.png]

在每种情况下基准都不使用任何性能标志而运行。

我们对比了 Java SE 5 和 Java SE 6 Update 2 之间的 VolanoMark™ 2.5 的性能。VolanoMark 是一个纯 Java 基准,用来测量 (a) 原始服务器性能和 (b) 服务器网络可伸缩性性能。在这个基准中,客户端积累了多达 4000 个并发套接字连接。只有那些成功积累连接多达 4000 个的虚拟机(VM)才能通过测试。在两种原始性能和网络可伸缩性测试中,分数越高,结果越好。


此项测试的平台为使用 24 x 1.5 GHz UltraSparc CPU 和 64 GB RAM 的 Sun Fire V890,操作系统为 Solaris 10

 

[volanomark.png]

在每种情况下,我们不使用任何性能标志而运行在回环(loopback)模式中的基准。显示结果基于相对吞吐量(使用 400 个回环连接每秒发送的消息)。

针对 Java SE 5 的完整 Java 版本是:

java 版本 “1.5.0”
Java(TM) 2 Runtime Environment,Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64,混合模式)


针对 Java SE 6 的完整 Java 版本是:

java 版本 “1.6.0_02”
Java(TM) 2 Runtime Environment,Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64,混合模式)


请阅读 VolanoMark™ 2.5 基准测试


在 Java SE 6 中的其他性能改进包括:

  • 在服务器级机器上,不低于或等于 1 秒的指定最大停顿时间目标将启用并发标记清除收集器。

  • 允许垃圾收集器根据需要(在规定的限制条件下)在年老代(tenured generation)和年轻代(young generation)边界之间迁移,从而获得更好的性能目标。该机制默认关闭;要激活该机制,将下列代码添加到命令行:option -XX:+UseAdaptiveGCBoundary

  • 对于串行(-XX:+UseSerialGC)收集器和并行年轻代(- XX:+ParNewGC)收集器 ,提升失败处理默认打开。如果在年老代中没有足够的空间来提升所有需要提升的对象,该项功能允许收集器启动小的收集(minor collection),然后把它取回来。

  • 已经实现了把来自年轻代的对象复制到在并行清除收集器中的年老代的可选命令。该项功能的意图是降低错过在年老代已经被访问的对象这类缓存错失次数。默认启用该项功能。要禁用该功能,请向命令行添加 -XX:-UseDepthFirstScavengeOrder。

  • 在 x86 平台上默认的年轻代的大小已经增加到 1MB。

  • 系统已经增加了并发标记清除收集器年轻代(Young Generation)的默认大小。

  • 最小年轻代大小从 4MB 增加到 16MB。

  • 针对年轻代的全部堆比例从 1/15 增加到 1/7。

  • 目前,并行标记清除(CMS)收集器默认使用生存空间,且其默认大小也有增加。
    这些变化的主要影响是通过减少垃圾收集开销来提高应用程序性能。但是,由于默认年轻代的大小比较大,应用程序也可能看到更大的年轻代停顿时间和更大内存占用量。

2.4 客户端性能增加


2.4.1 类数据共享中的新类列表


要减少应用程序的启动时间和内存占用量, Java SE 5.0 引入了一个称作“类数据共享(Class Data Sharing,CDS)”的功能。在 32 位平台上,这种机制按如下方式工作: Sun 提供了一个安装程序,从系统 jar(jar 文件包含所有 Java 类库,称作 rt.jar)文件中加载类集合到一个专有内部表示法,并将该表示法转储到一个称作“共享归档”的文件中。关于后续的 JVM 调用,共享归档是内存映射输入的,从而节省了加载这些类的开销,并允许许多 Java 虚拟机的元数据用于在被多个 JVM 进程之间共享的这些类。

在 Java SE 6.0中,在“共享归档”中的类列表已经被更新,以便更好反映对系统 jar 文件的更改。

2.4.2 引导类加载器的性能改进


已经增强了Java 虚拟机的引导(boot)和扩展(extension)类加载器性能以便改进 Java 应用程序的冷启动时间。在 Java SE 6 之前,打开系统 jar 文件引发 Java 虚拟机要读取一个 1 MB 大小的 ZIP 索引文件。当文件没有在磁盘缓冲区内时,该索引文件将文件转换为大量磁盘搜索活动。启用“类数据共享”,Java 虚拟机现在可以提供一个“元索引(meta-index)”文件(位于 jre/lib 中),其中包含在 jar 文件中所含包的高层次信息。

当 Java 应用程序类被加载时,这有助于 JVM 避免打开在引导和扩展类路径上的所有 jar 文件。要了解更多详细信息,查看错误 6278968}

下面我们给出了 Java SE 5 和 Java SE 6 Update 2 的应用程序启动时间性能对比图。此测试的运行环境为 1 GB 内存的 Intel Core 2 Duo 2.66GHz 台式机。

[specjbb.png]

应用程序启动对比结果显示了系统的相对性能(数值越小,性能越好),并且在基准运行的每种情况中都没有添加任何性能标志。

 

我们还比较了 Java SE 5 和 Java SE 6 Update 2 所需内存占用量的大小。
这项测试的运行环境是 1GB 内存的 Intel Core 2 Duo 2.66GHz 台式机:

[specjbb.png]

内存占用量对比结果显示了系统的相对性能(数值越小,性能越好),并且在运行基准的每种情况中都没有添加任何性能标志。


尽管新增了许多功能,但是 Java 虚拟机的核心内存利用率却大大削减,这使其对系统内存的实际影响比 Java SE 5 要低很多。

2.4.3 启动画面功能

Java SE 6 提供了一个使应用程序在虚拟机启动前显示启动画面的解决方案。目前,Java 应用程序的启动程序能够对图像进行解码,并在简单的未修饰窗口中显示该图像。

2.4.4 Swing 的真正双重缓冲

现在 Java SE 6 已经启用了 Swing 的真正双重缓冲功能。Swing 过去在应用程序的基础上提供双重缓冲;现在,在每一个窗口(per-window)基础上提供双重缓冲,并且将原生暴露事件直接复制到双重缓冲区。这样显著地提高了 Swing 的性能,特别在远程服务器上效果尤为明显。

有关更多详细信息,请访问 Scott Violet 的博客

2.4.5 改进 windows 系统的呈现功能

UxTheme API 允许在 Microsoft Windows 系统上启用窗口控制的标准外观呈现功能。Java SE 6 采用 UxTheme API 提高了 Swing Systems 外观的保真性。

 

3   新平台支持


有关完整信息,请参阅 支持 Java SE 6 的操作系统配置 图表。

3.1  运行环境


3.1.1   Windows Vista

Windows Vista Ultimate Edition、Home Premium Edition、Home Basic Edition、Enterprise Edition、Business Edition、Windows XP Home 和 Professional、2000 Professional、2000 Server 以及 2003 Server 都支持 Java SE 6。

4   深入学习

4.1 Java 性能门户


有关 Java 性能最佳实践、文档、工具、常见问题解答(FAQ)、代码样例和白皮书(White Papers)以及 Java 性能新闻中的其他最新信息,请访问 Java 性能门户

在此给出了 Java SE 6.0 三个特殊的相关性能链接:

4.1.1  Java SE 6 HotSpot[tm] 虚拟机垃圾收集调优

Java SE 6 HotSpot[tm] 虚拟机垃圾收集调优 文档针对 Java SE 6 垃圾收集(GC)调优概念和技术进行了扩展,这方面内容详见 使用 5.0 Java 虚拟机进行垃圾收集调优 文档。

4.1.2  jvmstat 3.0

jvmstat 3.0 主页提供了内建在 Java SE 6 中的轻量级性能监控功能,并解释了如何使用这些工具监控 6.0 HotSpot Java Virtual Machines、HotSpot 1.5.0、HotSpot 1.4.2 以及 1.4.1 JVM。

4.2   Java SE 6 文档


请阅读 Java SE 6 文档,其中包括 新功能及其增强Java Platform,Standard Edition 6 概述

4.3 性能监控与管理


4.4   基准测试


4.4.1   SPECjbb 2005

SPECjbb2000 是标准性能评估机构(Standard Performance Evaluation Corporation,SPEC)提供的一款基准测试工具。引用的性能建立在 Sun 内部软件测试基础之上,并遵循上面列举的方法。

有关最新的 SPECjbb2005 测试结果,请访问 http://www.spec.org/osg/jbb2005

4.4.2   VolanoMark™ 2.5

VolanoMark™ 版本 2.5 是 Volano LLC ( http://www.volano.com/ ) 提供的一款基准测试工具。