当应用程序性能受到损害时,大多数开发人员都惊慌失措,这在情理之中。跟踪java应用程序瓶颈来源一直以来都是很麻烦的,因为java虚拟机有黑盒效应,而且java平台分析工具一贯就有缺陷。
然而,随着java5中jconsole的引入,一切都发生了改变。jconsole是一个内置java性能分析器,可以从命令行或在guishell中运行。它不是完美的,但是当尖头老板来问你关于性能的问题时,用它来应对还是绰绰有余的——这比查询papagoogle要好得多。
我们将向您展示5个方法,使您可以轻松地使用jconsole(或者,它更高端的“近亲”visualvm)来监控java应用程序性能和跟踪java中的代码。
1.jdk附带分析器
许多开发人员没有意识到从java 5开始jdk中包含了一个分析器。jconsole(或者java平台最新版本,visualvm)是一个内置分析器,它同java编译器一样容易启动。如果是从命令行启动,使jdk在path上,运行jconsole即可。如果从guishell启动,找到jdk安装路径,打开bin文件夹,双击jconsole。
当分析工具弹出时(取决于正在运行的java版本以及正在运行的java程序数量),可能会出现一个对话框,要求输入一个进程的url来连接,也可能列出许多不同的本地java进程(有时包含jconsole进程本身)来连接。
使用jconsole进行工作
在java 5中,java进程并不是被设置为默认分析的,而是通过一个命令行参数—-dcom.sun.management.jmxremote——在启动时告诉java 5 vm打开连接,以便分析器可以找到它们;当进程被jconsole捡起时,您只能双击它开始分析。
分析器有自己的开销,因此最好的办法就是花点时间来弄清是什么开销。发现jconsole开销最简单的办法是,首先独自运行一个应用程序,然后在分析器下运行,并测量差异。(应用程序不能太大或者太小;我最喜欢使用jdk附带的swingset2样本。)因此,我使用-verbose:gc尝试运行swingset2来查看垃圾收集清理,然后运行同一个应用程序并将jconsole分析器连接到它。当jconsole连接好了之后,一个稳定的gc清理流出现,否则不会出现。这就是分析器的性能开销。
jconsole或visualvm?
2.远程连接进程
如果tomcat运行在一个名为“webserve”的机器上,且jvm已经启动了jmx并监听端口9004,从jconsole(或者任何jmx客户端)连接它需要一个jmx url“service:jmx:rmi:///jndi/rmi://webserver:9004/jmxrmi”。
基本上,要分析一个运行在远程数据中心的应用程序服务器,您所需要的仅仅是一个jmx url。
3.跟踪统计
jconsole有许多对收集统计数据有用的选项卡,包括:
◆memory:在jvm垃圾收集器中针对各个堆跟踪活动。
◆threads:在目标jvm中检查当前线程活动。
◆classes:观察vm已加载类的总数。
这些选项卡(和相关的图表)都是由每个java 5及更高版本vm在jmx服务器上注册的jmx对象提供的,是内置到jvm的。一个给定jvm中可用bean的完整清单在mbeans选项卡上列出,包括一些元数据和一个有限的用户界面来查看数据或执行操作。(然而,注册通知是在jconsole用户界面之外。)
使用统计数据
假设一个tomcat进程死于outofmemoryerror。如果您想要弄清楚发生了什么,打开jconsole,单击classes选项卡,过一段时间查看一次类计数。如果数量稳定上升,您可以假设应用程序服务器或者您的代码某个地方有一个classloader漏洞,不久之后将耗尽permgen空间。如果需要更进一步的确认问题,请看memory选项卡。
不要成为典型
发现应用程序代码中性能问题的常用响应多种多样,但也是可预测的。早期的java编程人员对旧的ide可能十分生气,并开始进行代码库中主要部分的代码复查,在源代码中寻找熟悉的“红色标志”,像异步块、对象配额等等。随着编程经验的增加,开发人员可能会仔细研究jvm支持的-x标志,寻找优化垃圾收集器的方法。当然,对于新手,直接去google查询,希望有其他人发现了jvm的神奇的“make it go fast”转换,避免重写代码。
从本质上来说,这些方法没什么错,但都是有风险的。对于一个性能问题最有效的响应就是使用一个分析器——现在它们内置在java平台,我们确实没有理由不这样做!
4.为离线分析创建一个堆转储
生产环境中一切都在快速地进行着,您可能没有时间花费在您的应用程序分析器上,相反地,您可以为java环境中的每个事件照一个快照保存下来过后再看。在jconsole中您也可以这样做,在visualvm中甚至会做得更好。
先找到mbeans选项卡,在其中打开com.sun.management节点,接着是hotspotdiagnostic节点。现在,选择operations,注意右边面板中的“dumpheap”按钮。如果您在第一个(“字符串”)输入框中向dumpheap传递一个文件名来转储,它将为整个jvm堆照一个快照,并将其转储到那个文件。
稍后,您可以使用各种不同的商业分析器来分析文件,或者使用visualvm分析快照。(记住,visualvm是在java 6中可用的,且是单独下载的。)
5.jconsole并不是高深莫测的
作为一个分析器实用工具,jconsole是极好的,但是还有更好的工具。一些分析插件附带分析器或者灵巧的用户界面,默认情况下比jconsole跟踪更多的数据。
jconsole真正吸引人的是整个程序是用“普通旧式java”编写的,这意味着任何java开发人员都可以编写这样一个实用工具。事实上,jdk其中甚至包括如何通过创建一个插件来定制jconsole的示例。建立在netbeans顶部的visualvm进一步延伸了插件概念。
如果jconsole(或者visualvm,或者其他任何工具)不符合您的需求,或者不能跟踪您想要跟踪的,或者不能按照您的方式跟踪,您可以编写属于自己的工具。如果您觉得java代码很麻烦,groovy或jruby或很多其他jvm语言都可以帮助您更快完成。
您真正需要的是一个快速而粗糙(quick-and-dirty)的由jvm连接的命令行工具,可以以您想要的方式确切地跟踪您感兴趣的数据。