最大化 AIX 上的 Java 性能,第 5 部分: 参考资料和结论

http://www.ibm.com/developerworks/cn/aix/library/es-Javaperf/es-Javaperf5.html

最大化 AIX 上的 Java 性能,第 5 部分: 参考资料和结论

这是由五个部分组成的系列的结束部分,此系列提供了相关技巧和技术,这些技巧和技术通常用于优化 Java™ 应用程序,以便在 AIX® 上实现最佳的性能。我们将讨论 AIX 上的 Java 性能优化的其他有趣方面,并查看几个案例研究,然后通过有用的参考资料列表结束此系列。

查看本系列更多内容 | 0 评论:

Amit Mathur ([email protected]), 高级技术顾问和解决方案实现经理, IBM

2008 年 1 月 03 日

  • 内容

在 IBM Bluemix 云平台上开发并部署您的下一个应用。

开始您的试用

引言

这是由五个部分组成的有关 Java 性能的系列的结束部分。本系列中的第一篇文章奠定了性能优化的基础,第 2、3 和 4 篇文章考虑了会影响系统可伸缩性和吞吐量的各种瓶颈。本文介绍两个先前未涉及到的重要主题,并提供案例研究和参考资料。

一个常见问题 (FAQ) 是如何将特定于 Sun 的命令行开关转换为特定于 IBM 的开关。此外,任何严格的性能优化工作,例如基准测试,都不能忽略系统范围的优化。我们将在下一个部分中简要讨论这些主题。

随后是几个案例研究,尝试说明如何应用本系列中描述的工具和技巧来解决实际中的问题。重点在于了解和学习如何使用本系列中提到的工具和技术。

最后通过回顾有用的参考资料结束本文和本系列。

回页首

其他重要注意事项

本部分讨论如何将 Sun Java 配置转换为 IBM Java 配置,以及针对 AIX 应用程序的系统范围的优化。这些主题的范围相当大,我们只是略微触及皮毛。

转换 Sun Java 开关

如果您有一个为 Sun Java 而优化过的应用程序,并且正在尝试将应用程序迁移到 AIX(或迁移到任何运行 IBM Java 的平台),您可能已经完成了最艰巨的工作。了解应用程序特征只是成功的一半。基于对使用 Sun Java 进行优化工作的了解,您可以使用第 2 部分第 3 部分 中阐述的优化技巧。

但是,我们经常收到有关如何将特定 Sun Java 命令行开关转换为等效的 IBM Java 命令行开关的询问。这些开关几乎始终对应于垃圾收集,因为经过充分优化的 GC 对任何基于 Java 的应用程序的性能都非常重要。由于 JVM 体系结构方面的区别,Sun 和 IBM 开关之间的映射非常困难。IBM Java 没有包含分代的垃圾收集器 (Generational Garbage Collector),并且不支持任何以 -XX 开头的命令行开关。IBM Java 的“完全独立”体系结构也不基于 Sun HotSpot 体系结构。最容易并且在大多数情况下最快的方法是在 IBM 平台上运行应用程序时丢弃所有特定于 Sun 的设置,并根据需要进行微调。但是如果您对某些 Sun 开关如何映射到 IBM 开关感到好奇,请继续阅读。

下表尝试将 Sun Java GC 命令行开关转换为等效的 IBM 开关。此映射基于特定于 Sun 的文章“Tuning Garbage Collection with the 1.4.2 Java™ Virtual Machine”中描述的 Sun 开关的功能。此表只用于定位 IBM Java 的等效(或近似)开关这个非常特定的目的。这并不意味着取代优化实践,因为即使是堆大小要求也会差异相当大。有关 IBM Java 的一般 GC 优化技巧,以及有关 IBM Java 的这些和其他 GC 开关的信息,请参见“Fine-tuning Java garbage collection performance”。此表的创建并不涉及任何性能相关的测试,而是完全基于上面引用的参考资料中的 Sun 开关用法的文档记录。

Sun 开关 等效的 IBM 开关 说明
-Xms、-Xmx -Xms、-Xmx 这些参数及其含义保持不变。您仍然需要执行堆大小调整。
-XX:SurvivorRatio、-XX:NewSize、 
-XX:MaxNewSize、-XX:NewRatio
这些开关可简单地删除,因为它们用于 GC,而 GC 不适用于 IBM Java。
-XX:MinHeapFreeRatio、-XX:MaxHeapFreeRatio -Xminf、-Xmaxf 堆扩展/收缩受其他因素而不只是受这些开关的控制。
-Xverbose:gc、-XX:+PrintGCDetails -Xverbose:gc IBM Java 的 verbosegc 跟踪格式与 Sun GC 区别相当大。可以根据需要启用更详细的跟踪,但是在大多数情况下,缺省的 verbosegc 跟踪就足够了。
-XX:+UseParallelGC、-Xincgc、-XX:+AggressiveHeap 这些是 Sun 支持的各种类型的垃圾收集器。它们不适用于 IBM Java。
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -Xgcpolicy:optavgpause 并发低暂停 (Concurrent Low-pause) 收集器的作用接近于 IBM 并发标记(但在设计上是不必要的)。
-XX:+CMSParallelRemarkEnabled 不适用于 IBM Java。
-XX:ParallelGCThreads -Xgcthreads 至少对于 IBM Java,更改此设置是不可取的。
-Dsun.rmi.dgc.client.gcInterval、-Dsun.rmi.dgc.server.gcInterval -Dsun.rmi.dgc.client.gcInterval、-Dsun.rmi.dgc.server.gcInterval 请参见第 4 部分中的技巧 NIO003。

正如上表所示,大多数情况下,把 Sun 平台上的开关转换到 IBM 平台的方式就是丢弃这些开关。这使得针对 IBM Java 的GC 优化工作相当简单,同时仍然提供卓越的性能。

系统范围的优化

使用诸如 schedo 和 vmo 等 AIX 工具具有系统范围的影响,因此对这些工具的全面介绍超出了本系列的范围。有关这些工具的更多信息,请参见参考资料部分。

但是对于大多数多层应用程序(尤其是基准测试),系统范围的优化是不可避免的。存在若干可用于 AIX 性能优化的优秀资源可供您参考。要了解通常需要的优化类型,您可以查看实际的已发布基准。如果查看最近针对 AIX 上的 IBM Java 的 SpecJBB 2000 结果,比方说 http://www.spec.org/osg/jbb2000/results/res2003q3/jbb2000-20030624-00194.html,则操作系统优化如下所示:

操作系统优化

  • SPINLOOPTIME=2000
  • vmo -r -o lgpg_regions=256 -o lgpg_size=16777216
  • setsched -S rr -P 40 -p $$
  • schedtune -t 400 -F 1
  • vmtune -S 1

警告:切勿在没有充分了解后果的情况下应用这些设置,因为不正确使用这些设置实际上会恶化系统性能。

那么上述设置有何作用呢?参阅 AIX 文档,您很快就可以更好地了解这其中每个设置是做什么用的。让我们依次研究一下其中每个设置。

SPINLOOPTIME 控制系统在让步于另一个进程之前重试某个繁忙锁的次数。由于缺省值为 40,更高的值将告诉系统应该尝试更长的时间以待锁释放。在多处理器系统上,这样会导致更好的性能,因为忙锁重试的开销要比进程上下文切换的开销低。

vmo 行设置大型页的大小和数量。查看一下 Java 命令行开关,您将看到正在使用 -Xlp。该开关启用 Java 中的大型页支持,白皮书”AIX Support for Large Page“对该开关进行了更详细的描述。如果您有内存密集型应用程序,可以试验大型页以确定它是否有帮助。与 Java 配套的 SDK 指南中提供了有关此主题的更多信息。

setsched 行实际上是一个脚本而不是 AIX 命令。它调用 thread_setsched 内核服务以选择固定优先级的循环调度,并对该 Java 进程使用优先级 40。

schedtune 命令也是 AIX 5.2 以上版本中的一个脚本,它将传递的参数映射到新的 schedo 命令。上面这一行命令是将固定优先级线程的时间片更改为 400 个计时单元。它还强制固定优先级的线程驻留在全局运行队列中。

最后,vmtune 命令将该调用转换为等效的 vmo 调用,并且上面的行还启用了共享内存段的固定。

因此可以看到系统被切换到大型页和固定优先级的调度程序,以达到 SpecJBB 2000 基准的记录数据。您能否在自己的应用程序中使用这些相同的设置呢?也许不能,但是您现在能够研究这些命令和调度策略,并进行试验以适合自己的应用程序特征。这是性能优化中的下一步。

回页首

案例研究

在本部分中,我们将查看一些示例,这些示例取自 Java Service 团队处理过的具体问题。这些示例能够让您清楚了解如何进行性能优化,以及如何使用各种工具来收集可用于性能优化工作的信息。请注意,本部分的案例不是基于问题在实际工作中的出现频率来选择的。重点在于了解如何使用本系列中讨论的各种工具和技术来定位和纠正性能问题。

案例 1 糟糕的应用程序响应时间

报告的问题是基于 Java 的应用程序的响应时间不可接受。使用 topas,然后使用 vmstat,结果发现 Java 是消耗最多 CPU 的应用程序。使用 tprof,出现的函数中具有 GC 相关的术语,因此这指示可能存在 Java 堆大小调整方面的问题。

观察 GC 日志确认了堆扩展得太频繁。这与接二连三的多次分配故障和非常满的堆相结合,导致了 Java 应用程序花大量的时间尝试分配空闲块,未找到空闲块,扩展堆,然后仅满足当前分配请求。

这可以通过为 -Xmine 指定更大的值来修复,从而迫使堆增长得更快(请参见第 3 部分中的技巧 MEM003)。其结果是单次扩展即可避免多次潜在的分配故障。

第一步是使用 AIX 工具来确认这是与 Java 相关的问题。在 AIX 工具指示这是与 GC 相关的问题这个事实的指导下,第二步可以是直接集中于 GC 日志。第三步是使用可用的优化参数来中断应用程序陷入的异常周期,从而允许恢复多余的 CPU 时间。

案例 2JVMPI 让您绝处逢生

另一个有趣的场景是作为性能问题提出的,其中 CPU 在大多数时间都处于繁忙状态。通过查看 verbosegc,我们看到有一个 GC 周期被调用的太过频繁,从而导致应用程序的大多数时间只是花在执行 GC 上。

verbosegc 跟踪表明,大多数 GC 活动都是由于超大型对象的多次分配所导致的,该对象的大小约为 10 MB 或更大。这些活动导致了堆碎片,使得 GC 周期更长,从而影响了性能。但是通过查看 verbosegc 周期,客户无法确定这些对象是什么。

确定问题根源的最容易方法是使用 HeapRoots 工具来分析堆转储 (heapdump)。但是该场景还存在另一个难解之处:那些大型对象并没有存活到 GC 周期之后。因此堆转储没有显示任何具有此类大小的对象。

对于定位和纠正应用程序源代码中的问题来说,这是分析(profiling)如何能够成为有用助手的经典示例。Java 虚拟机分析接口 (Java Virtual Machine Profile Interface) 使得此问题变得微不足道。对于这个特定示例,我们使用了 Using JVMPI to Identify Large Memory Allocations 上描述的方法的一种变化形式,并且能够快速确定执行此分配的代码。

案例 3无限增长

作为本文的最后一个案例研究,我们将讨论一个其表现似乎为简单的大小调整问题的场景。曾经尝试将该应用程序扩展到 1000 个用户,并且应用程序将会耗尽 Java 堆空间。基于用户数量来计算堆需求后,将堆大小从 1 GB 增加到了 1.5 GB。

但是这样触发不是由于 Java 堆带来的 OOM 错误。Java 堆显示了足够的空闲空间,但应用程序日志表明发生了 OOM。通过使用 svmon,发现仅有大约 4 个段(或 1 GB)用于本机堆,第四个段似乎差不多是空的(请参见“Getting more memory in AIX for your Java applications”中的“Balancing Memory”)。

为了进一步深入研究,我们添加了命令行开关 -verbose:jni。作为此开关的结果而打印的额外消息表明全局 JNI 引用池被耗尽了,发生这种事情是非常少见的。全局 JNI 引用池足够大,以确保大多数正常应用程序决不会耗尽它(甚至是接近耗尽它)。

一般情况下,我们尝试通过增加 JNI 引用数量来绕过该问题(如果指定更高的 -Xoss 值,则会呈比例地增加上限)。但这只是延迟了不可避免的问题,大量的固定 JNI 引用导致的严重 Java 堆碎片并没有任何好转。

进一步研究应用程序的设计揭示了真正的根源:应用程序创建了无限数量的线程。随着测试的继续,线程将等待终结器,而且由于终结器是不可预测的,因此存在大量的此类线程在等待释放它们的 JNI 引用。在此情况下,唯一可行的解决方案是更改应用程序代码以纠正这两个问题。一旦应用程序将无限数量的线程替换为线程池,并且尽可能替换终结器,大小调整工作就胜利完成了。

此案例表明,有时候问题的原因是一些深层次的因素。Java 堆耗尽的问题最终证明是设计问题。Java 和本机堆的平衡通常是性能优化的关键部分,但在此例中是不足够的。手边拥有如此多的工具和技术可以让您了解更全面的情况,使您能够做出应该优化什么对象的精明决策。

回页首

结束语

本文将结束整个系列。希望本系列成为最大化 AIX 上的 Java 应用程序性能的宝贵指南。

作者要感谢 Ashok Ambati、Rajesh Jeyapaul、Sharad Ballal、Roger Leuckie 和 Mark Bluemel 为这些文章提供的帮助和建议。特别要感谢 John Tesch,他的有关 AIX Java 性能的信息集合是本系列的主要灵感之源。

参考资料

学习

时间: 2024-10-16 17:45:04

最大化 AIX 上的 Java 性能,第 5 部分: 参考资料和结论的相关文章

最大化 AIX 上的 Java 性能,第 1 部分: 基础

http://www.ibm.com/developerworks/cn/aix/library/es-Javaperf/es-Javaperf1.html 最大化 AIX 上的 Java 性能,第 1 部分: 基础 这个由五个部分组成的系列提供了若干技巧和技术,这些技巧和技术通常用于优化 Java™ 应用程序,以便在 AIX® 上实现最佳的性能.其中还提供了有关每个技巧的适用性讨论.使用这些技巧,您应该能够快速优化 Java 环境,以适合应用程序的需要. 引言 存在若干可用于运行 AIX 的

最大化 AIX 上的 Java 性能,第 4 部分: 监视流量

http://www.ibm.com/developerworks/cn/aix/library/es-Javaperf/es-Javaperf4.html 最大化 AIX 上的 Java 性能,第 4 部分: 监视流量 这个由五个部分组成的系列提供了若干技巧和技术,这些技巧和技术通常用于优化 Java™ 应用程序,以便在 AIX® 上实现最佳的性能.本文讨论 I/O 和网络可能成为瓶颈的情况. 查看本系列更多内容 | 0 评论: Amit Mathur ([email protected]),

最大化 AIX 上的 Java 性能,第 2 部分: 速度需求

http://www.ibm.com/developerworks/cn/aix/library/es-Javaperf/es-Javaperf2.html 最大化 AIX 上的 Java 性能,第 2 部分: 速度需求 这个由五个部分组成的系列提供了若干技巧和技术,这些技巧和技术通常用于优化 Java™ 应用程序,以便在 AIX® 上实现最佳的性能.其中还提供了有关每个技巧的适用性讨论.使用这些技巧,您应该能够快速优化 Java 环境,以适合应用程序的需要. 查看本系列更多内容 | 0 评论:

推荐:Java性能优化系列集锦

Java性能问题一直困扰着广大程序员,由于平台复杂性,要定位问题,找出其根源确实很难.随着10多年Java平台的改进以及新出现的多核多处理器,Java软件的性能和扩展性已经今非昔比了.现代JVM持续演进,内建了更为成熟的优化技术.运行时技术和垃圾收集器.与此同时,底层的硬件平台和操作系统也在演化. 目录: 一.Java性能优化系列之一--设计优化 二.Java性能优化系列之二--程序优化 三.Java性能优化系列之三--并发程序设计详解 四.Java性能优化系列之四--Java内存管理与垃圾回收

Java性能调优笔记

Java性能调优笔记 调优步骤:衡量系统现状.设定调优目标.寻找性能瓶颈.性能调优.衡量是否到达目标(如果未到达目标,需重新寻找性能瓶颈).性能调优结束. 寻找性能瓶颈 性能瓶颈的表象:资源消耗过多.外部处理系统的性能不足.资源消耗不多但程序的响应速度却仍达不到要求. 资源消耗:CPU.文件IO.网络IO.内存. 外部处理系统的性能不足:所调用的其他系统提供的功能或数据库操作的响应速度不够. 资源消耗不多但程序的响应速度却仍达不到要求:程序代码运行效率不够高.未充分使用资源.程序结构不合理. C

java性能优化技巧

一.通用篇 "通用篇"讨论的问题适合于大多数 Java应用. 1.1     new 1.1     new 11..11 不用 nneeww关键词创建类的实例 用new 关键词创建类的实例时,构造函数链中的所有构造函数都会被自动调用.但如 果一个对象实现了Cloneable 接口,我们可以调用它的clone()方法.clone()方法不会调用任 何类构造函数. 在使用设计模式(Design Pattern)的场合,如果用 Factory模式创建对象,则改用clone() 方法创建新的

JAVA性能优化的五种方式

一,JAVA性能优化之设计优化 设计优化处于性能优化手段的上层.它往往须要在软件开发之前进行.在软件开发之前,系统架构师应该就评估系统可能存在的各种潜在问题和技术难点,并给出合理的设计方案,因为软件设计和系统架构对软件总体设计质量有决定性的影响.所以,设计调优对系统的性能影响也是最大的,假设说,代码优化.JVM优化都是对系统微观层次的"量"的优化,那设计优化就是对系统"质"的优化. 设计优化的一大显著特征是:它能够规避某一个组件的性能问题,而是改良组件的实现;比方:

关于 Java 性能监控您不知道的 5 件事,第 1 部分

责怪糟糕的代码(或不良代码对象)并不能帮助您发现瓶颈,提高 Java? 应用程序速度,猜测也不能帮您解决.Ted Neward 引导您关注 Java 性能监控工具,从5 个技巧开始,使用Java 5 的内置分析器JConsole 收集和分析性能数据. 当应用程序性能受到损害时,大多数开发人员都惊慌失措,这在情理之中.跟踪 Java 应用程序瓶颈来源一直以来都是很麻烦的,因为 Java 虚拟机有黑盒效应,而且 Java 平台分析工具一贯就有缺陷. 然而,随着 Java 5 中 JConsole 的

Java性能监控工具:VisualVM

VisualVM是一款免费的,集成了多个 JDK 命令行工具的可视化工具,它能为您提供强大的分析能力,对 Java 应用程序做性能分析和调优.这些功能包括生成和分析海量数据.跟踪内存泄漏.监控垃圾回收器.执行内存和 CPU 分析,同时它还支持在 MBeans 上进行浏览和操作.本文主要介绍如何使用 VisualVM (JVM 监控)进行性能分析及调优. 自从 JDK 6 Update 7 以后已经作为 Oracle JDK 的一部分,位于 JDK 根目录的 bin 文件夹下,无需安装,直接运行即