Java常用的性能分析工具记

1.VisualVM

VisualVM是一个资源分析工具,一直从JDK 6更新到7,它默认内存和CPU的监视,它可以告诉你哪个类和方法消耗资源,但它不会显示代码流程。 

2.JProfiler

JProfiler很容易安装,并且通过向导,你可以选择应用服务器用来运行应用程 序。我不得不选择使用JPofiler应用服务器的主目录,以及向导生成的一个单独的启动脚本。然后运行服务器。在监听会话的过程中,它会提供几个选项, 它可以记录内存的使用和CPU的使用率。在查看CPU使用率的同时,可以看到执行路径。这让我看到应用程序大部分时间都花在请求上。我们可以将 IntelliJ插件安装到IDE上,那么运行JProfiler会更加便利。比如,可以直接帮我启动Tomcat。

4.JProbe

我刚开始创建JProbe时遇到点困难。安装并不是直接完成,我需要对它进行配置。它 采用了类似JProfiler一样的设置。它会在你的Tomcat目录中生成启动脚本,可以通过脚本启动服务器并监听会话。它的界面包含有按钮和表格,其 中可以看到内存的使用,但无法在进程中找到执行路径。

JProbe提供了三种类型的分析:

  • 内存分析,使开发人员可以发现和解决Java内存泄露和对象循环,以确保最佳的方案效率和稳定性。
  • 性能分析,使开发人员可以识别和解决Java的瓶颈,死锁,以确保最佳的性能和可扩展性方案。
  • l覆盖分析,使开发人员在单元测试,以确定关联代码执行的线路,以确保测试范围和程序的正确性。
  • JProbe还提供一个Eclipse插件,提供了在Eclipse Java IDE内智能代码性能分析和解决问题。

     

    JProbe让您可以

  • 实现一个可靠的,系统的工作流程,全面验证并提供优化的代码
  • 轻松跟踪性能增强的代码变化,从生成到生成的质量的提高
  • 利用自动性能分析和度量报告,确保及时审查和修正
  • 在生成过程中诊断问题通过调优提高生产力问题
  • 避免不必要的,昂贵的添置硬件来解决性能问题
  • 通过Eclipse插件鼓励自动化内存测试和代码优化最佳实践
  • 启用JProbe跨应用程序生命周期开发和整合阶段主动的性能管理,作为Quest Java技术和门户应用管理的一部分,为企业预生产开发团队提供深层次的性能,内存和覆盖分析能力。通过一个统一,直观的控制台,JProbe提供了三种强大的分析工具:

JProbe Memory - 内存分析工具可以帮助您快速找出和诊断内存泄漏和过剩垃圾收集的根本原因。它可以帮助您快速找到并修复低效的代码,创建游离对象(挥之不去的引用)和导致内存不足系统崩溃和较低性能的对象循环。

JProbe Performance - 性能分析工具可以帮助你快速找出和诊断代码瓶颈和线程竞争背后的根本原因。它可以帮助您快速找到产生瓶颈,死锁,陷入僵局的线程,并修复低效的代码,从而避免导致整体性能缓慢和可扩展性瘫痪。

JProbe Coverage - 覆盖分析工具通过精确测量的陈述和已经行使条件可以帮助您找到在开发早期未经测试的应用程序代码,从而更容易评估测试运行的可靠性和准确性。

自动化

JProbe允许在夜间构建过程分析内存,性能和覆盖。 JProbe利用ANT(或Maven)构建任务,JUnit测试脚本和一个称为触发器的独特功能来实现自动化分析。触发器是JProbe自动化的基石,处理更精细的既简单又复杂的自动化活动。通过启用触发器,您免去了应用程序代码生成过程中插入额外的控制代码进行运行测试,它可以帮助您节省宝贵的时间和预留预算分析。

3.YourKit

YourKit是我在另一个项目中偶然发现的一款性能分析工具,它的安装很简单。安装 时有一个选项,可以安装一个插件到我的IDE。安装后,运行应用程序,使用该插件,它会自动连接到YourKit。它有一个漂亮的用户界面可以查看到内存 和CPU的监测,同时也可以看到请求的执行路径。

5.Spring Insight

听到TC Server有Spring Insight监控界面,于是我兴奋地尝试了一下。安装完成后,并设置成TC Server的开发者版,然后部署应用程序在TC Server上。我查看Insight界面,它可以很好的监视类和方法,并能看到完成这个方法用了多少时间。我还能看到输入参数值,以及返回值。由于我的 应用程序是基于Spring的,Spring Insight能够提供非常有用的数据。TC Server插件在IDE上的配置与Tomcat的配置类似。SpringSource工具套件就自带Spring Insight。

6.jconsole

方便不用下载安装,在JDK的bin目录下就有,如图。

 

7.JMeterJMeter

可以用于测试静态或者动态资源的性能(文件、Servlets、Perl脚本、java对象、数据库和查询、ftp服务器或者其他的资源)。 JMeter用于模拟在服务器、网络或者其他对象上附加高负载以测试他们提供服务的受压能力,或者分析他们提供的服务在不同负载条件下的总性能情况。你可 以用JMeter提供的图形化界面分析性能指标或者在高负载情况下测试服务器/脚本/对象的行为。

8.JRockit Mission Control

Mission Control BEA JRockit JVM 自带的一组以极低的开销来监控、管理和分析生产环境中的应用程序的工具。它包括三个独立的应用程序:内存泄漏监测器( Memory Leak Detector )、 JVM 运行时分析器( Runtime Analyzer )和管理控制台( Management Console )。 BEA JRockit R26 版本就开始捆绑这个工具套件,目前最新的版本是 3.0 。最近我们使用其中的 Runtime Analyzer 对国内某著名行业解决方案进行性分析和调优。

JRockit Runtime AnalyzerJRA)是一个JVM分析器,是一个随需应变的“动态记录器”。它记录了Java应用程序和JVM在一段预定的时间内的详细记录。然后通过JRA应用程序对记录下来的文件进行离线分析。所记录的数据包括对方法的调用跟踪、错误的同步、锁定的分析,还有垃圾收集统计信息,优化决策以及对象统计信息和其他重要的应用程序/JVM行为。它的目的是让JRockit开发人员能够找到良好的方法来基于现实应用程序优化JVM,对于帮助客户在生产和开发环境中解决问题十分有用。

在本次项目中,操作 |A 和操作 B 的百人并发脚本执行完成的时间接近两分钟,因此我们使用 JRA 进行了 2 分钟 (120 ) 的记录。在 GC 常规信息中,我们发现在短短两分钟时间内,垃圾收集的总数高达 365 次,而由此造成的暂停时间有 42.5 秒之多。也就是说 35% 的执行时间是在做垃圾收集。
 
因为最大堆尺寸已经设置成 1024M ,对于 32 位操作系统上的 Java 应用已经是足够大了(在 IA32 构架下,由于操作系统给每个进程的最大内存寻址空间为 1.8G ,因此最大堆尺寸不能超过 1.8G ),因此堆的大小并不是造成频繁垃圾收集的原因。那么在高并发度的场景下,可能的影响因素很可能是 Nursery 大小。
 
Nursery 也称为新代,是指运行分代式垃圾收集器时,在堆中分配 新对象 的可用块区域。 Nursery 变满时,会在新垃圾收集中单独对其进行垃圾收集。 Nursery 大小决定了新收集的频率和持续时间。较大 Nursery 会降低收集的频率,但是会稍微增加每个新收集的持续时间。 Nursery 之所以具有价值,是因为 Java 应用程序中的大多数对象都是在新代中夭亡的。与收集整个堆相比,应首选从新空间中收集垃圾,因为该收集过程的开销更低,而且在触发收集时,新空间中的大多数对象均已死亡。 在新收集过程中, JVM 首先确定 Nursery 中的哪些对象是活动的,此后将它们提升到旧空间,并释放 Nursery ,供分配新的小对象使用
 
Nursery 的默认缺省值是 10M/CPU ,对于我们 Clovertown 服务器来说,只有 20M 。由于出现频繁收集的情况,那么我们推断是由于 Nursery 的默认值太低的原因。一方面在高并发用户的场景下,肯定是有大量的新对象产生,那么 Nursery 的空闲空间很容易就被耗尽。因此 Nursery 发生垃圾收集频率就会比较高。另一方面更短的垃圾收集间隔会使得新对象在 Nursery 的存活率提高因为很多新对象可能还没来得及使用完毕就已经发生垃圾收集。这样更多的对象会被提升到旧代,使得旧代的对象也会急剧增加,从而使得旧代发生垃圾收集的频率也增加。
 
因为 JRockit JVM 可以使用 -Xns:<size> 来设置 Nursery 的尺寸,我们要在保证垃圾回收停顿时间( garbage collection-pause )尽可能短的同时,尽量加大 Nursery 的尺寸,这在创建了大量的临时对象时尤其重要。推荐值是最大堆尺寸的 10% ,因此我们在 JRockit 的运行时参数上添加了 –Xns100m 。再次运行脚本后, JRA 收集的信息显示 GC 暂停时间骤降到 15.3s ,次数也有所减少,降到 296
 
Nursery 大小
20M( 默认值 )
100M
GC 暂停时间
42.5s
15.3s
垃圾收集的总数
365
296
平均暂停时间
116ms
52ms
 
此外,我们从方法信息中可以看到调用次数最多耗时间最长的两个方法分别是 jrockit.vm.Locks.monitorEnterSecondStage com.ABC.StateManager.makeState 两个方法。展开前置任务后发现调用这两个方法最多的方法是 com.ABC.SqlQueryAction.query 。而 jrockit.vm.Locks.monitorEnterSecondStage 显然是 JRockit 实现锁机制的特定的 API 。因此我们怀疑是对数据库的操作时有资源互斥的现象发现。
 
考虑到高并发用户的场景下,对数据库操作的并发度也很高,因此对数据库连接的争用比较激烈。我们察看了一下当时 WebLogic JDBC 的配置,发现 connection pool 的大小只是缺省值 20 ,相对来说偏小了,对性能会有一定的影响。因此我们增大 connection pool 的大小到 100 。重新运行测试脚本后发现性能有较大提升。
 
 
 
JDBC connection size 20  w/ default nursery
JDBC connection size 100 w/ 100M nursery
Increase %
 
操作 A
22.125
12.079
83%
操作 B
35.195
21.773
62%
 
 
在性能调优完成后,我们又进行了功能测试(回归测试),以验证上述改动没有影响系统的功能性正确。

总结:

看到这七款性能分析工具,我可以肯定地说,它们都非常不错。如果你有基于Spring的应用程序,那么选择Spring Insight显然是最佳的。它一直是免费的,但你需要部署你的应用在TC Server上。

如果你想监听本地和远程的进程,我会选择JProfiler或YourKit.这两个也可以帮助Spring Insight来监测、找到性能瓶颈。

JProfiler和YourKit已经能满足我的上述要求。JProfiler、 YourKit和Spring Insight都可以跟踪应用程序的类和方法的流向。JProfiler和YourKit可以显示内存使用情况。虽然Spring Insight不可以显示内存使用情况,但它可以很好的显示吞吐量的趋势。这三款性能分析工具功能很清楚,不混乱,而且容易使用。最后,他们都有自己的 IDE插件。

猜你喜欢

转载自talentluke.iteye.com/blog/1870794