副标题#e#
关于Java机能监控您不知道的5件事,第2部门:操作JDK内置阐明器举办Java历程监控
全成果内置阐明器,如 JConsole 和 VisualVM 的本钱有时比它们的机能用度还要高 — 尤其是在出产软件上运行的系统中。因此,在聚焦 Java 机能监控的第 2 篇文章中,我将先容 5 个呼吁行阐明东西,使开拓人员仅存眷运行的 Java 历程的一个方面。
JDK 包罗许多呼吁行实用措施,可以用于监控和打点 Java 应用措施机能。固然大大都这类应用措施都被标注为 “尝试型”,在技能上不受支持,可是它们很有用。有些甚至是特定用途东西的种子质料,可以利用 JVMTI 或 JDI成立。
1. jps (sun.tools.jps)
许多呼吁行东西都要求您识别您但愿监控的 Java 历程。这与监控当地操纵系统历程、同样需要一个措施识别器的同类东西没有太大区别。
“VMID” 识别器与当地操纵系统历程识别器(“pid”)并不老是沟通的,这就是我们需要 JDK jps 实用措施的原因。
在 Java 历程中利用 jps
与设置 JDK 的大部门东西及本文中提及的所有东西一样,可执行 jps 凡是是一个环绕 Java 类或执行大大都事情的类集的一个薄包装。在 Windows® 情况下,这些东西是 .exe 文件,利用 JNI Invocation API 直接挪用上面提及的类;在 UNIX® 情况下,大大都东西是一个 shell 剧本的标记链接,该剧本回收指定的正确类名称开始一个普通启动措施。
假如您但愿在 Java 历程中利用 jps(可能任何其他东西)的成果 — Ant 剧本 — 仅在每个东西的 “主” 类上挪用 main() 相对容易。为了简化引用,类名称呈此刻每个东西名称之后的括号内。
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 统计数据被分类到 “选项” 中,这些选项在呼吁行中被指定作为第一参数。对付 JDK 1.6 来说,您可以通过回收呼吁 -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 毫秒为 10 个佚代执行一次 gc 快照转储,然后遏制:
jstat -gc 5756 250 10
请留意 Sun(此刻的 Oracle)保存了在不举办任何预先通知的环境下变动各类选项的输出甚至是选项自己的权利。这是利用不受支持实用措施的缺点。请参看 Javadocs 相识 jstat 输出中每一列的全部细节。
#p#副标题#e#
3. jstack (sun.tools.jstack)
相识 Java 历程及其对应的执行线程内部产生的环境是一种常见的诊断挑战。譬喻,当一个应用措施溘然遏制历程时,很明明呈现了资源耗尽,可是仅通过查察代码无法明晰知道那里呈现资源耗尽,且为什么会产生。
jstack 是一个可以返回在应用措施上运行的各类百般线程的一个完整转储的实用措施,您可以利用它查明问题。
#p#分页标题#e#
回收期望历程的 VMID 运行 jstack 会发生一个堆转储。就这一点而言,jstack 与在节制台窗口内按 Ctrl-Break 键起同样的浸染,在节制台窗口中,Java 历程正在运行或挪用 VM 内每个 Thread 工具上的 Thread.getAllStackTraces() 或 Thread.dumpStack()。jstack 挪用也转储关于在 VM 内运行的非 Java 线程的信息,这些线程作为 Thread 工具并不老是可用的。
jstack 的 -l 参数提供了一个较长的转储,包罗关于每个 Java 线程持有锁的更多具体信息,因此发明(和 squash)死锁或可伸缩性 bug 是极其重要的。
4. jmap (sun.tools.jmap)
有时,您正在处理惩罚的问题是一个工具泄露,如一个 ArrayList (大概持有成千上万个工具)该释放时没有释放。另一个更普遍的问题是,看似从不会压缩的扩展堆,却有活泼的垃圾收集。
当您尽力寻找一个工具泄露时,在指按时刻对堆实时举办照相,然后审查个中内容很是有用。jmap 通过对堆拍摄快照来提供该成果的第一部门。然后您可以回收下一部门中描写的 jhat 实用措施阐明堆数据。
与这里描写的其他所有实用措施一样,利用 jmap 很是简朴。将 jmap 指向您但愿拍快照的 Java 历程的 VMID,然后给以它部门参数,用来描写发生的功效文件。您要通报给 jmap 的选项包罗转储文件的名称以及是否利用一个文本文件或二进制文件。二进制文件是最有用的选项,可是只有当与某一种索引东西 团结利用时 — 通过十六进制值的文本手动操纵数百兆字节不是最好的要领。
随意看一下 Java 堆的更多信息,jmap 同样支持 -histo 选项。-histo 发生一个工具文本柱状图,此刻在堆中大量引用,由特定范例耗损的字节总数分类。它同样给出了特定范例的总示例数量,支持部门原始计较,并揣摩每个实例的相对本钱。
不幸的是,jmap 没有像 jstat 一样的 period-and-max-count 选项,可是将 jmap(或 jmap.main())挪用放入 shell 剧本或其他类的轮回,周期性地拍摄快拍照对简朴。(事实上,这是插手 jmap 的一个好的扩展,不管是作为 OpenJDK 自己的源补丁,照旧作为其他实用措施的扩展。)
5. jhat (com.sun.tools.hat.Main)
将堆转储至一个二进制文件后,您就可以利用 jhat 阐明二进制堆转储文件。jhat 建设一个 HTTP/HTML 处事器,该处事器可以在欣赏器中被欣赏,提供一个关于堆的 object-by-object 视图,实时冻结。按照工具引用纰漏处理惩罚堆大概会很是好笑,您可以通过对总体杂乱举办某种自动阐明而得到更好的处事。幸运的是,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
您可以查找 OQL 的完整语法及其在 jhat 欣赏器情况内 “OQL Help” 页面上的特性。将 jhat 与 OQL 相团结是对行为不妥的堆举办工具观测的有效要领。
竣事语
当您需要近间隔调查 Java 历程内产生的工作时,JDK 的阐明扩展会很是有用。本文中先容的所有东西都可以从呼吁行中由其本身利用。它们还可以与 JConsole 或 VisualVM 有力地团结利用。JConsole 和 VisualVM 提供 Java 虚拟机的总体视图,jstat 和 jmap 等有针对性的东西支持您对研究举办微调。