java 性能监控_Java性能监控,第2部分

诸如JConsole和VisualVM之类的功能齐全的内置探查器有时在性能开销上的花费比其所值得的还要多,尤其是在生产硬件上运行的系统中。 因此,在第二篇专注于Java性能监视的文章中,我将介绍五个命令行分析工具,这些工具使开发人员可以仅关注正在运行的Java进程的一个方面。

JDK包含许多命令行实用程序,可用于监视和管理Java应用程序性能。 尽管它们大多数被标记为“实验性”,因此在技术上不受支持,但它们仍然有用。 有些人甚至可能是可能使用JVMTI或JDI内置专用工具的种子材料(见相关主题 )。

1. jps(sun.tools.jps)

许多命令行工具要求您标识要监视的Java进程。 这与监视本机操作系统进程并需要进程标识符才能工作的类似工具没什么不同。

“ VMID”标识符并不总是与本机操作系统进程标识符(“ pid”)相同,这就是为什么我们需要JDK的jps实用程序。

jps (其名称反映了大多数UNIX系统上发现的ps实用程序)告诉我们正在运行的Java应用程序的JVMID。 顾名思义, jps返回给定计算机上运行的所有可发现Java进程的VMID。 如果jps找不到进程,则并不意味着Java进程无法附加或伪造。 这只是意味着它没有在宣传自己。

如果可以找到Java进程,则jps将列出用于启动它的命令行。 区分Java进程的这种方法很重要,因为就操作系统而言,所有Java程序都是“ java 。 对于大多数目的,VMID是要注意的重要数字。

探查器入门

开始使用概要分析实用程序的最简单方法是使用演示程序,例如位于demo/jfc/SwingSet2的SwingSet2演示程序。 这样做可以避免进程作为后台/守护进程运行而造成潜在的麻烦。 熟悉该工具及其开销后,您可以在实际程序中尝试使用它。

加载演示应用程序后,运行jps并记下返回的vmid 。 为了获得最佳效果,请启动带有-Dcom.sun.management.jmxremote属性集的Java程序。 如果您不使用此设置,则以下某些工具收集的某些数据将不可用。

2. jstat(sun.tools.jstat)

jstat实用程序可用于收集各种不同的统计信息。 jstat统计信息被分类为在命令行中指定为“第一个参数”的“选项”。 您可以通过使用命令-options运行jstat来查看可用选项列表。 清单1中显示了一些选项:

清单1. jstat选项
-class
-compiler
-gc
-gccapacity
-gccause
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcpermcapacity
-gcutil
-printcompilation

该实用程序的JDK文档(请参阅参考资料 )将告诉您清单1中每个选项返回的内容,但是大多数选项用于收集有关垃圾收集器的性能信息,或仅收集其中的一部分。 -class选项显示已加载和已卸载的类(使其成为检测应用程序服务器或您的代码内的ClassLoader泄漏的强大实用程序),并且-compiler-printcompilation显示有关Hotspot JIT编译器的信息。

默认情况下, jstat将在您检查信息时显示该信息。 如果要定期拍摄快照,请在-options命令后指定间隔(以毫秒为单位)。 jstat将连续显示受监视进程信息的快照。 如果希望jstat在终止前拍摄特定数量的快照,请在时间间隔/期间值后指定该数量。

如果5756是几分钟前开始运行的SwingSet2进程的VMID,则以下命令将告诉jstat每250毫秒生成一次gc快照转储,进行10次迭代,然后退出:

jstat -gc 5756 250 10

请注意,Sun(现为Oracle)保留在不发出警告的情况下更改各种选项甚至选项本身的输出的权利。 这就是使用不受支持的实用程序的缺点。 有关jstat输出中各列的完整详细信息,请参见Javadocs。

3. jstack(sun.tools.jstack)

相对于执行线程,了解Java进程内部正在发生什么是一个常见的诊断挑战。 例如,当应用程序突然停止处理时,很明显已经达到某种程度的饥饿,但是仅通过查看发生饥饿的代码或原因,这并不明显。

jstack是一个实用程序,可返回在应用程序中运行的各种线程的完整转储,然后可以使用该转储查明问题。

使用所需进程的VMID运行jstack将生成堆栈转储。 在这方面, jstack工作原理与在运行Java程序的控制台窗口中按Ctrl-Break或在VM中的每个Thread对象上调用Thread.getAllStackTraces()Thread.dumpStack()jstack调用还会转储有关VM中运行的非Java线程的信息,这些信息并不总是作为Thread对象提供。

jstack-l参数提供了一个稍长的转储,其中包含有关每个Java线程持有的锁的更详细的信息,因此在发现(和压榨!)死锁或可伸缩性错误方面非常有价值。

4. jmap(sun.tools.jmap)

有时,您要处理的问题是对象泄漏,例如ArrayList (它可以容纳数千个对象),在应有的情况下不会被释放。 另一个更普遍的问题是正在扩展的堆,尽管活动了垃圾回收,但堆似乎从未收缩。

当您尝试查找对象泄漏时,在给定的时间对堆进行拍照,然后查看其中的内容,这非常有用。 jmap通过为堆拍摄快照来提供该功能的第一部分。 然后,您可以使用下一部分中介绍的jhat实用程序分析堆数据。

就像这里介绍的所有其他实用程序一样,使用jmap非常简单。 只需将jmap指向要快照的Java进程的VMID,然后为其提供一些参数来描述生成的结果文件。 您将传递给jmap的选项包括要转储到的文件的名称以及是使用文本文件还是二进制文件。 二进制文件是最有用的选项,但是仅当与某种索引工具结合使用时–手动填充几兆字节的十六进制值填充文本并不是花一天时间的最佳方式。

为了更轻松地浏览Java堆, jmap还支持-histo选项。 -histo生成当前在堆中强烈引用的对象的文本直方图,按该特定类型消耗的字节总数排序。 它还提供了该特定类型的实例总数,这允许进行一些原始计算并猜测每个实例的相对成本。

不幸的是, jmap不像jstat那样具有周期和最大计数选项,但是jmap.main() jmap (或对jmap.main() )的调用放入Shell脚本或其他类的循环中相对容易定期拍摄快照。 (实际上,这是添加到jmap一个很好的扩展,可以作为OpenJDK本身的源补丁或作为另一个实用程序的扩展。)

5. jhat(com.sun.tools.hat.Main)

将堆转储到二进制文件后,可以使用jhat分析二进制堆转储文件。 jhat创建了一个HTTP / HTML服务器,可以在浏览器中对其进行浏览,从而给出了冻结的按对象的堆的逐个视图。 虽然遍历堆,逐个对象引用可能很有趣,但最好通过对整个混乱进行某种自动分析来更好地为您服务。 幸运的是, jhat支持OQL语法来进行该分析。

例如,对所有100个以上字符的String进行OQL查询,如下所示:

select s from java.lang.String s where s.count >= 100

结果显示为指向对象的链接,然后显示该对象的完整内容,该字段引用其他对象作为可以取消引用的其他链接。 OQL查询还可以在对象本身上调用方法,将正则表达式用作查询的一部分,并使用内置查询工具。 一种查询工具referrers()函数显示所有引用给定类型对象的引用程序。 这是查找所有File对象引用者的查询:

select referrers(f) from java.io.File f

您可以在jhat浏览器环境中的“ OQL帮助”页面下找到OQL的完整语法及其功能。 将jhat与OQL结合使用是对行为异常的堆进行有针对性的调查的有效方法。

结论

当您需要仔细了解Java进程内部发生的情况时,JDK的概要分析扩展非常有用。 本文介绍的所有工具都可以从命令行中单独使用。 它们还可以与JConsole或VisualVM强大地结合在一起。 JConsole和VisualVM提供了Java虚拟机的总体视图,而专门关注的工具(如jstatjmap使您可以微调调查。

尽管这些工具仍然很常用,但是Java 7引入了JCMD,它是一个单一的实用程序,可以处理其他实用程序执行的许多操作。 您可以使用它来识别Java进程ID(类似于jps ),获取堆转储(如jmap ),进行线程转储(与jstack )以及生成垃圾收集统计信息(就像jstat一样)。


翻译自: https://www.ibm.com/developerworks/java/library/j-5things8/index.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值