导航目录:
慨述
分析器原理
三种产品的快速比较
测试平台
Borland Optimizeit Suite
Quest Software的 JProbe Suite
ej-technologies的 JProfiler
结束语
概述
谁实现Java应用程序的时候不出点问题?嗯,让我们诚实一点吧...代码分析器就是解决这个普遍问题的唯一的自定义工具。在本文中, Laurence Vanhelsuwé将为您回顾三种商用的Java分析器:Borland的Optimizeit Suite、 Quest Software的 JProbe Suite、以及ej-technologies的JProfiler。
现在的软件是一个如此笨重的、如此多面性的家伙,以致没有一个开发工具可让程序员随心所欲的完成他们的构想。甚至是运行--这个难以捉摸的尺度,当我们的代码在二档挣扎时恨得它要死;而当我们的代码以一档的速度运行时,我们却爱得它要命--它包含了太多相关方面。
性能方面公认的问题有:主观的用户感知程序速度及响应速度。如果我们暂时排除用户方面的因素,那么评价运行速度就等于客观实现方面的总和。这些方面有:算法选择、整体内存的使用、对象的动态分配和释放、以及多线程设计与运行行为。帮助你理解你的程序在运行时的维数选择就是代码分析器的繁重工作。
在本文中,我考虑了三种商用Java分析器并且判断出哪一种分析器更容易满足你我的需要:
· Borland的 Optimizeit Suite
· Quest Software的JProbe Suite
· ej-technologies的JProfiler
分析器原理
不必惊奇,这三种产品有许多共同点。所有现代分析器都是从同一个起点和约束开始的: Java 虚拟机分析器界面(JVMPI) (参考其他栏的 "The Java Virtual Machine Profiler Interface")。Sun微系统的API允许工具开发商接口或者连接到遵循JVMPI的JVM上,并且监控运作的方式以及JVM运行任何Java程序时的关键事件--从单独的应用程序到 applet、servlet和企业JavaBeans (EJB)组件。
假定JVMPI强加给所有的分析器工具开发商一个标准的、同等的游戏场,那么区分开发商高低的因素只在于工具的元特征(如,添加重要数值到原始JVMPI数据和功能上的特征,更为重要的是,绘图用户界面(GUI)应该针对这些特征进行开发),这也应该没什么稀奇的了。
在你看到该产品回顾的余下部分的时候,它的每一个自我形成或者自我突破的GUI都有自己的方法来解决如何开发原始的JVMPI 特征的核心问题,以便可以最大化分析和调试的效率。不幸的是,很多用到大型数据库的应用程序都采用可视化的、直观的真正友好的用户界面,但没有一个分析器能说服我:它们在这方面做得比较成功。
回顾的这三个分析器几乎都有着同样的分析会话期配置能力。所以在这我只是简短的提一下,并且继续进行比较:
· JVM 选择
· 要分析的程序的选择
· CLASSPATH 和资源路径选择
要启动评价会话期,所有这三种产品都要求你选择JVM,我们通常JVM上运行应用程序。一旦你选择了JVM,你必须指定你的程序的主类,或者可执行的jar文件,如果你的程序要参数的话,也要指定哪种参数 。最后,为评价会话期设置CLASSPATH通常也要你指明你的源代码层上的工具。图1展示了一个典型的会话期配置对话框。
Figure 1.
在分析器内启动一个程序意味着生成、捕捉、和观察大量数据,所以所有的分析器都包含着不同的方法来控制数据的流动,在不同的标准以及每一封装包的基础上进行过滤。同样也可以使用灵活的正规表达式类型模式如java.util.*或者jav*来完成。
三种产品的快速比较
在我探究具体的分析器特征(和非特征)之前,表格1 展示了每个产品关键点的属性矩阵:
Table 1.属性矩阵
| Optimizeit Suite | JProbe Suite | JProfiler |
版本 | 5.0 | 5.0 | 2.2.1 |
价格 | $1,599 | $2,0001 | $499 |
免费评价 | Yes | Yes | Yes |
在线(安装)帮助 | Yes | Yes (JavaHelp) | Yes (JavaHelp)2 |
有无上下文相关帮助? | Yes | Yes | Yes |
安装指南 | Yes | Yes | No3 |
白皮书文件 | No | Yes | No |
工具模块数 | 3 (Profiler, Thread Debugger,Code Coverage) | 4 (Profiler, Coverage,Memory Debugger,Threadalyzer) | 0 (all-in-one) |
工具模块是否单独出售? | No | Yes | No |
CPU 分析器 | Yes (不实时) | Yes (不实时) | Yes (实时) |
对象/堆栈 分析器 | Yes | Yes | Yes |
线程分析器 | Yes | Yes | Yes |
死锁检测 | 自动并可见 | 自动 | 手动 |
路径条件检测 | No | Yes | No |
代码覆盖 | Yes | Yes | No |
多JVM支持 | Yes | Yes | Yes |
深入到源代码 | Yes | Yes | Yes |
深入到字节码 | No | Yes | Yes |
远程评价* | Yes | Yes | Yes |
自动评价** | Yes | Yes | Yes |
IDE 集成 | Yes | Yes | Yes |
生成报告 | Yes | Yes | Yes |
主机平台许可政策 | 多平台和单一平台许可 | 单一平台许可 | 多平台 |
网址 | http://www.borland.com/optimizeit/ | http://www.jprobe.com/ | http://www.jprofiler.com/ |
易于使用度 | 7/10 | 4/10 | 8/10 |
注释:
* 远程评价:在你的开发设备之外的其它设备上评价你的Java程序的执行
** 自动评价:实现无人看管的通宵的评价会话期;换句话说,不使用GUI驱动的命令列队
1 JProbe Suite的价格包含一年的Gold Support (即技术支持)
2 ej-technologies的JProfiler的在线帮助几乎不包含任何的视图或者对话栏
3 ej-technologies'缺乏明确的指南将由某些演示会话期作出补偿
测试平台
我惊喜地发现:从对宿主操作系统(OS)到对JAVA虚拟机的不同版本, 分析器对不同的平台都有广泛的支持。实际上,大多数分析器支持每一个与商业相关的主机和/或JVM实现(这归功于大量的排列,查看更多细节请浏览开发商的产品网站)。一个例外就是Borland和 Quest Software的分析器都不支持Windows 98。据说是因为Windows 98 在实时精确度的处理方面不是一个"认真的"OS。(Windows 98通过它的公共API显然只能提供50-ms嘀嗒信号的精确度, 毫无疑问,通过这样一个粗糙的计时器的网络许多方法将会以失败告终)所以,在一个配置为900-MHz Athlon CPU、256 MB RAM 、运行Windows XP (Service Pack 1)的单独的PC机上,我把这三个分析器都测试了一下。
为了方便组织这篇回顾,我将测试限制在单独的Java 2平台、标准版(J2SE)应用程序内。 尽管这三种分析器明确表示支持servlet评价或者运行在不同应用服务上的EJB组件,他们的开发商也想借此尽力打进J2EE市场,但我还是没有测试Java 2 Platform、 企业版(J2EE)应用程序。
你必须熟知应用程序的结构和实现,才能从使用分析器中获得新知识,所以我主要依赖于我自己的两个真实的作为评价试验品使用的应用程序(见下面的表格2)。
Table 2. 配置的应用程序
程序名 | World-on-a-Disc | Slave |
描述 | 用于CD/DVD-ROM的基于映射的多媒体引擎See http://www.worldonadisc.com/ | 普通的可插文件和目录处理器See www.lv2.clara.co.uk/slave.html |
实现的"唯一致命弱点" | CPU-bound | I/O-bound |
包含的类的数目 | 35 | 60+ |
所有这三个分析器都配送小型的演示应用程序。在使用这些工具评价程序之前,我觉得很有必要熟悉每个分析器,所以我干脆将它们的演示程序都玩了一遍。
Borland Optimizeit Suite
Borland的Optimizeit Suite是三者中最成熟,功能最齐全的分析器包。定价$1,599 , Borland无疑并不想占领独立开发者市场。它的分析器由三个自由耦合的组件组成: Optimizeit Profiler、 Optimizeit Thread Debugger和Optimizeit Code Coverage。
Borland Optimizeit Suite的核心特征
Borland的Optimizeit分析器是用于CPU和堆栈/对象评价的组合工具包。图2展示了一个典型的GUI屏幕快照。
Figure 2. Optimizeit Profiler的类实例图:好看,但不中用。
图2的类实例图将现实中的对象分布制成表格,按类分组并且按照对象的多少进行排序。如果你之前没有使用过堆栈分析器,请对此做好准备:不但在这个镜头中看到的你的程序低层实体可能完全让你感到迷惑,而且一旦你迷惑了,你同样看不到你的程序的源代码。
Borland的分析器允许你点击任何类并且看清分配了的该类的实例所在的位置。分析器不但告诉你存在分配的方法在哪里(见图3),而且只要你双击方法名,就会弹出一个分配语句行的源代码阅读器。
Figure 3. Optimizeit 分析器的对象分配回溯图。
如果你的程序饱受分配热点(即程序的某部分分配了太多的对象)之苦,或者你想追踪你程序中不应该出现的真实对象的来源(如XML解析器中的抽象窗口工具包(AWT)的有颜色的对象,或者混乱出现在只应该出现命令行的实体中的Swing 对象),那么上述特征就非常非常有用了。
存储检漏仪(Memory Leak Detector)允许你比较你的程序的堆栈的两种瞬象,从而有希望找出被引用的对象中有多少就要断裂的被遗漏的对象。注意,尽管这个工具称做存储检漏仪,而且它也大大的削减了大海捞针的范围,但检测存储漏洞仍然是一件艰巨的手工劳动。
分析器的实例演示(Instance Display)也揭示存储漏洞。 这个工具可让你深入到对象图表的极度精微的程序。你可以分析你的应用程序中的任何一个真实对象的进出索引。我对这个实例演示的疑问就是: Borland没有为了工具的这个部分而使用传统的可视化图表;相反,这个工具使用的是表格和树的综合,如图4所示。
Figure 4. Optimizeit 分析器的对象实例视图。
线程调试器被放在Borland的分析器的第二个模块内。它由所有真实线程以及它们状态(运行,等待,调度,在本机输入/输出(I/O)设备上的阻塞)的实时显示,再加上几种其它的可帮助你分析死锁和资源瓶颈的视图组成。在实时的视图中,每个线程行告诉你对象锁定多少--程序称作"监控器"--线程有多少以及该线程锁住多久了。图5举例说明了一个典型的线程调试会话期。
Figure 5. 线程调试器的默认视图显示实时线程活动和状态。
如果你曾经花过一段时间调试线程问题的话,你肯定会同意下列特征使得线程调试器非常有价值:直接死锁检测和可视化(见图6)、线程争用、线程等待、和附加嵌套的锁定分析。
Figure 6.线程调试器包含检测和显示死锁的逻辑。
Borland 的三件套中的第三个模块Code Coverage,作了一件相当好的工作,它向你展示 所有你系统的线程所观察到的程序部分。这个综合图将类按百分比列出,点击任何类都会弹出执行行用黄色显示的源代码视图。
Borland Optimizeit Suite的缺陷
Borland的三件套结构还不如一个结构,因为它只是一个将三个完全不同的程序放在一起的缺乏弹性的皮带。这就是说,如果你正在使用分析器,接下来又想使用线程调试器做一些线程分析,那你就要切换程序并启动一个全新的会话期。这就不是我们所说的模块组集成了。
线程调试器确实可以使用过滤器特征,它可让你调整你必须费力完成的数据的数量。目前,你不得不观察所有的真实的线程(从任何线程组信息中剥离出来的),就像观察颜色编码的彩虹带卷动的传送带一样:漂亮,但要将信号从噪音中分离出来并不是一件十分容易的事情。 反映Java线程组层级的分层观察特征也不会出现什么差错。另外,时间表示的格式也可以改进:不打印Thread-2 waited 23507561 ms,改为Thread-2 waited 6 h:31 m:47.561 s 可能更会受到程序员的欢迎。
Optimizeit只要用字节显示对象,它就会使用124b的格式。像我这样一个已经灌了一些东西到许多的十六进制垃圾桶的老黑客,这种格式总是触发十六进制的 "B" déjà vu。我的大脑已经大大地将同样的信息格式化成124字节。
Code Coverage的源代码显示也是有一点花架子:它只是用黄色使得执行的代码行突出,而剩下的均为白色(即不突出显示)。这种方法看起来当然不错,但如果它也认为紧挨被执行的代码之后的白色部分(包括注释)也同样的被执行,那这个特征将会有用的多。结果可能要好看得多得多,在显示的间隙还可以显示线程没有涉及的代码。
Quest Software的 JProbe Suite
Quest Software的JProbe Suite 在功能和价格上与Borland的Optimizeit Suite差不多。它也提供独立的工具模块来解决评价问题,模块有四: JProbe Profiler、JProbe Coverage、JProbe Memory Debugger、和JProbe Threadalyzer。
与其他两个分析其发行商不同,Quest Software单独发售个别模块组件;如JProbe Profiler一个就要$849 (包括一年的技术支持)。
JProbe Suite的关键特征
JProbe的评价方法集中在JVM实现数据瞬象的概念上。你可以为了以后的重新装载和后续的分析保存瞬象,并且比较两种瞬象以找出差别。图7 显示了一个典型的JProbe Profiler窗口,它包含两个用于分析的瞬象。
Figure 7. 一个典型的高级JProbe GUI显示用于(静态)分析的评价瞬象。
敲击一下,中心瞬象方法表示多数JProbe分析已经离线,不再是实时的了。这种方法对于堆栈分析很有意义,但是对于CPU实现评价就过于严格了。
对于CPU评价的所有重要的任务来说,JProbe要么提供表格式视图(如图8),要么提供图表式视图(如图9)。它没有提供让你深入到调用堆栈分支的直觉的Swing JTree类型的视图。
Figure 8. 一个典型的JProbe Profiler表格显示收集的实时方法。
Figure 9. 用图表显示的JProbe 实时方法。
JProbe的第二个模块,Memory Debugger允许你使用多种方式对堆栈瞬象进行操作。 它也包含一个简单而有效的使用实例分析的功能,它允许你在启动使用实例之前重新设置收集的数据。Memory Debugger也允许你定义任何实例数的计算限度(Quest Software有点模糊地称之为"断言"),在使用实例结束的时候,如果类生成的对象超过了你的期望值这个计算限度就会提醒你。图10显示了JProbe的堆栈概要图。
Figure 10. JProbe的堆栈概要图是Memory Debugger模块的主视图。
Memory Debugger的实例细节图(图11)让你可以分析出哪个对象涉及到了焦点对象以及焦点对象涉及到了哪个对象。
Figure 11.
引用图表视图(图12)允许你以一种辉煌但经常无法抵抗的图表细节来分析流入和流出的引用。
Figure 12.
如果缠在一起的意大利面条对你来说听起来就好比听二十世纪七十年代的减速火箭的话, Memory Leak Doctor显示的对象引用链有产生存储遗漏的潜在可能(图13)。Leak Doctor 可让你在一个堆栈瞬象上实现"如果我删除一个引用会怎样"的试验,并且看看这种操作能否解决你的存储遗漏问题。
Figure 13.
Memory Debugger的又一个有用的性能是Garbage Monitor;它可以追踪用于暂时存在的对象如幕后的对象StringBuffer之类的分配热点。这种对象可使用语法级的字符串进行串联(与API级别的串联相反)。
JProbe的 Threadalyzer是JProbe Suite的线程分析模块,并有着足以自豪的、可以自动检测问题的许多有用的性能。这些问题有:
· 死锁(现有的和潜在的)
· 线程迟延
· 数据竞争
但是,解决这些以外的其他方面的性能,GUI就远远没有那么直观了。
JProbe Suite的活页(纸)文件的编写和设计(在布局、屏幕快照的使用、和图标方面)应该说做得相当好。而且更进一步的是,它还告诉读者一些有价值的技术性能分析的方法和技巧,并且就如何将分析集成到你的软件开发方法中去提出一些基本的建议。
JProbe Suite的缺陷
尽管JProbe在工具市场占的份额高,我对于它的粗糙和不成熟仍然感到失望。它看起来感觉就像一个存在了多年但是却没有从偶尔的信手重新设计这种增长需求中获益的软件。因此JProbe Suite 5.0则在经典的"特征化"的重压下呻吟。我发现JProbe只有极少数方面才真正直观或者功能相当强大。学会使用JProbe是一件真正困难的任务。Memory Debugger中从左边、右边和中间弹出的GUI很不直观,尤其让人感到迷惑,而且我在许多的地方彻底迷惑了。
其它的JProbe 问题有(无固定顺序):
· 难于解释和交互的图形显示(图形和方法定时)
· 由混乱的十六进制数识别对象,而不是由它们的更为启发性的toString()表示法识别。
· 工具栏图标对于我的二十英寸、1280 x 1024 像素的屏幕来说实在是太小了。
· 方法适时表格只显示文字数字的数据信息,而不是文本、图表和颜色的综合信息。
· 在下列三种模块的表格中使用了三种不同的外观:Code Coverage、 Garbage Monitor和 Profiler。
· 好像标准的Swing组件没有用在表格中,导致了没有一个标准的外观。
· 太多不同的窗口/视图很少表现出整体的连贯性或者主要构思。
· 在线帮助有时递交的是被破坏的文本(可能在JProbe使用的JavaHelp中出现故障)。
· 数不清的窗口通过一大串按钮点击来连接,但是却没有返回/前进机制。
· 报告打印可以删掉:PDF产生之后发送到Acrobat Reader(安装一下就可以了)。我的测试设备上已经有了一个Acrobat 4.0 ,但是Acrobat 与报告打印模式不兼容:"文件打开出现错误。文件不存在"。
· 在Code Coverage模式中,Generate Report对话框打开时竟然比我的1024行的桌面还要高(OK 和Cancel 按钮完全不在屏幕上了!)
ej-technologies的 JProfiler
如果你以前没听说过ej-technologies公司,那也没什么好惊奇:作为一个2001年才成立的德国公司,ej-technologies公司在Java工具市场确实是后起之辈。它在2002年2月发行JProfiler 1.0版本,并在2003年4月发行它的2.2.1版本(本文提到过)。(它同时也生产开放式源代码Java类库类文件API 和类阅读器。JProfiler使用这类阅读器 )ej-technologies公司的诞生和旗舰产品的问世代表着JProfiler的设计已经从巨大数量的后见之明中获益:它的GUI比Quest Software公司的JProbe Suite要容易操作的多。
JProfiler的核心性能
JProfiler 与前面两个分析器差别甚大,因为它采用了可以检测不同分析尺度的统一工具: 他只由一个工具组成。这个工具只是使用了四种不同的视图设置,可让你从不同角度分析你的程序,而且不必重启会话期或者切换到不同的程序。比起那些工具片断组合来说,这个方法的简单性和对称性要讨人喜欢,要有意义的多。而且在那些工具中,用户接口相互不连贯,功能判断也比较武断,这些缺点把工具的优势全破坏掉了。
四种JProfiler 视图设置是:
1. 存储视图(堆栈和对象图表分析)
2. CPU 视图(方法适时性)
3. 线程视图
4. VM 遥测视图
这些视图可以细分到形成产品中心的子视图。图14显示的Profiler有自己的关键Views下拉菜单。
Figure 14.
尽管Views菜单清楚地反映出产品的整体结构,视图之间的快速切换只需要在左边的垂直工具栏中点击就可以了,然后在窗口按钮的跳格键中随意地选择一个指定的类型。
方法计时可用作方法调用树,它可以显示时间消耗和绝对时间消耗的百分比。图15显示的正是这种树。
Figure 15. JProfiler的调用树视图(三个CPU视图中的一个)。
JProfiler允许你左击与调用树的每一行关联的上下文菜单 ,从而深入到消耗周期方法的源代码或者字节码。单个线程或者线程组可过滤方法评价的信息。JProfiler 也有一个子视图,它可列出由JVM识别的代码热点,这些代码已经编译成本地代码。
几种存储视图支持堆栈分析。图16显示的监控器子视图与Borland 的类似。
Figure 16. JProfiler的类监控器视图(四个存储视图中的一个)。
将高端技术指标集成到一个易于操作的GUI上,这是一件了不起的事情,但JProfiler的Heap Walker 模块(图17)却是它的唯一败笔。它的六个子视图的子视图更象一个程序内部的程序,它应该集中解决它的有效使用问题,而不是扩展产品的其它性能。
Figure 17. JProfiler's Heap Walker 主页图。
线程视图设置的五个子视图集中处理:线程的过去状态和当前状态(运行、等待、和阻塞)、监控器的过去使用和当前使用、以及监控器的统计表。这些视图比直接观察原始数据要好一点。但是这些视图中没有一个可以自动的智能的帮助你识别竞争条件、死锁、或者线程的其他噩梦。图18显示的是一个典型的线程视图。
Figure 18.
VM 遥测视图设置的五个不同的实时滚动曲线图显示:堆栈空间的使用情况和空闲情况、对象数(有助于分出排列和非排列两类)、已经装载的类数、垃圾收集器的活动、和线程数。图19 显示了这种视图设置。
Figure 19.
JProfiler的缺陷
JProfiler的 CPU 分析器中缺少的一个简单特征就是Reset或者Clear Data命令。 例如,当你分析一个Swing应用时,应用程序装载和初始化过程中收集的数据,与激活应用程序某个特征时收集的数据,这两种性能数据有着本质的差别。但是,一旦装载了测试应用程序,我就会清除纪录,以便集中处理具体的使用案例。目前, JProfiler不支持这种基本分析模式。
JProfiler的在线帮助过于简单,它缺乏实例、详细的指南以及GUI屏幕快照。尽管JProfiler 是这三个分析器中最直观地分析器,但是缺乏足够的在线帮助使得它的Heap Walker 模块更难理解。
结束语
尽管不用分析器对你的应用程序进行评价也有可能编写出稳定的Java应用程序,但你也知道啃下这块硬骨头将带给你许多许多麻烦。任何连续运转几天或者几个星期(甚至几个月)不间断的应用程序必须确认是稳定的。为了这个,你必须十分彻底地逐条测试你系统的内部运行行为。
所有这三个分析器都能处理我的两个实验应用程序。在我的900-MHz的设备上,分析器的评价活动减慢了应用程序的速度,但是分析器分析或者调试任务的活动却没有。
在这三个分析器中,我喜欢Borland的 Optimizeit Suite和ej-technologies的JProfile,当然它们还是有潜力改进的。ej-technologies的JProfiler的价格还是很有竞争力的,它对于小规模的公司的吸引力很大,但是大一点的公司毫无疑问会青睐 Borland的 Optimizeit Suite ,因为它的功能设置要丰富一些。如果你为你的团队挑中Optimizeit,注意Borland的 JBuilder 8.0和9.0 (企业版)已经包含了集成到JBuilder IDE 上的Optimizeit Suite 5.0。
最后,我不得不承认,为了推荐Quest Software的JProbe Suite,我的头都大了。评价现实生活中的Java系统是一件高技巧、高技能、和费时的工作,而且你最不想见到的一件事就是:分析器使得你的工作更加困难,你会发现它不但没有简化你的工作,而是把它弄得更加复杂。JProbe Suite 的许多性能需要改造的地方就是改进GUI的设计,使得它具有整体连贯性,因为现在的它分析代码时太不连贯了,让人老是感觉灰心,简直是无法忍受了。