IBM i 上 Java 分析工具的介绍

J9 作为 IBM i 上 Java 虚拟机的趋势,有越来越多的 Java 应用程序不断从 Classic JVM 向 J9 移植。如何管理和诊断 Java 在 J9 上的问题尤为显得重要起来。本文主要介绍 IBM i 上提供的 J9 相关工具,以及分析方法。包括 i 6.1 及以上所提供的 WRKJVMJOB 等的相关工具以及 STRSST 中提供的相关宏的介绍。本文选择一些笔者在工作和实践过程中经常使用的功能和选项进行讲解,并穿插一些常见问题的总结和思考。

张 干, IBM i J9 Team Lead, IBM

张干,来自IBM 中国系统与科技研发中心 IBM i J9 团队,具有多年的 C/C++/Java 从业经验,目前主要负责 IBM i 上 J9 VM的开发和维护工作。



高 丽, 软件工程师, IBM

高丽,来自 IBM 中国系统与科技研发中心 IBM i J9 团队,目前主要负责 IBM i 上 JVM 的开发工作。



王 国坤, 软件工程师, IBM

王国坤, 来自IBM 中国系统与科技研发中心 IBM i J9 团队从2012年开始在IBM i的J9团队从事J9 JDK的测试与开发的工作。



2013 年 1 月 31 日

IBM Technology for Java(IT4J) 是 IBM 的 Java 虚拟机,它也是 IBM i 操作系统中的 Java 虚拟机的趋势。我们通常称此 java 虚拟机为 J9。

不同于其他操作系统,J9 在 IBM i 上有一些统一的管理和分析工具,如 WRKJVMJOB, PRTJVMJOB 以及 GENJVMDMP。除了这些简单易用的工具以外,还有一些 STRSST 应用程序中提供的功能以及相关的宏。所有这些工具和宏可以帮助用户更好的管理系统中所有的 J9 相关的作业,同时对于有问题的作业进行分析和数据搜集工作。下面我就分别对于一些常用的工具进行说明。

IBM i 上 J9 介绍

V1 是 Java 虚拟机在 IBM i 上的产品名称,如 i 5.4 上的 5722JV1 和 i6.1 和 i7.1 上的 5761JV1。 值得一提的是,JV1 这个产品是作为 IBM i 操作系统的一部分分发给最终用户的,所以不需要花费额外的费用就可以把不同版本的 J9 安装到 IBM i 系统上使用 , 并且可以得到 IBM 的技术支持。 不同版本的 J9 占用了 JV1 产品的不同选项,如下表:

表 1 JV1 产品选项和 J9 JDK 版本之间的关系如下 :
J9 版本JV1 选项IBM i 5.4IBM i 6.1IBM i 7.1
JDK 1.4.2 64 位13不支持支持支持
JDK 5.0 32 位8支持支持支持
JDk 5.0 64 位9不支持支持支持
JDK 6.0 32 位11支持支持支持
JDK 6.0 64 位12不支持支持支持
JDk 7.0 32 位14不支持不支持支持
JDK 7.0 64 位15不支持不支持支持

本文中将以选项 11, JDK 6.0 32bit 为例进行工具的讲解和分析。


WRKJVMJOB 工具

首先我们来看看 WRKJVMJOB。这个工具是一个非常常用和有效的管理 IBM i 上所有 J9 作业的工具。它主要可以用来完成显示和管理 J9 作业,主要涉及以下几个领域:

  • 环境变量显示
  • JVM 参数显示
  • Java 系统属性显示
  • 垃圾回收信息显示
  • Java 锁显示
  • Java 线程显示
  • 产生 Java,堆以及系统 dump
  • 控制垃圾回收日志

我们将在后面的章节里面逐一讲解 WRKJVMJOB 的使用。

WRKJVMJOB 基本操作

WRKJVMJOB 命令的参数中有作业,以及选项。当作业的参数可以唯一确定一个作业时,选项将对这个作业起作用,否则,这个选项将被忽略。例如下面的这个命令就可以直接进入到 044210 作业的垃圾回收信息窗口中。

WRKJVMJOB JOB(044210/QSYS/QSVRMSERMD) OPTION(*GC)

具体的参数描述,可以使用 F1 功能键来参考 WRKJVMJOB 的帮助信息。在 IBM i 上,这通常是一个非常有效的办法。

默认情况下,WRKJVMJOB 将会列举出系统中所有的 J9 作业,如下所示:

图 1. WRKJVMJOB 列举所有 J9 作业
图 1. WRKJVMJOB 列举所有 J9 作业

在这个窗口中我们可以看到系统中存在两个 J9 作业,分别有作业名称,作业编号,用户名称等信息。通过功能键 F11 可以看到关于每个作业的更详细信息,例如线程数量,进程编号,子系统等等。

对于每一个 J9 的作业,我们有 5,7,8,9,11,12,13 等 7 个选项可以使用。除 5 以外的选项可以被认为是 5 选项后的子选项的快捷方式。为介绍方便,我就不在此具体介绍每个快捷方式选项了。我们来选择一个作业然后用 5 选项进入更加详细的管理界面中。如下显示:

图 2. 每个 J9 作业可用选项列表(一)
图 2. 每个 J9 作业可用选项列表(一)
图 3. 每个 J9 作业可用选项列表(二)
图 3. 每个 J9 作业可用选项列表(二)

在这两个窗口的顶部,分别列出了作业的基本信息,以及使用的 J9 JDK 的类型,此作业使用的是 JDK 6.0 32 位

WRKJVMJOB 具体选项

随后的部分就是对任一 J9 作业进行的操作列表,分别在以上两个图的中部,从 1 到 50。当然你也许已经注意到这个数字列表并不是连续的。

WRKJVMJOB 选项 1,它是用来查看虚拟机参数的。当我们使用 java 命令的时候,我们可以给虚拟机指定一些参数(比如 -Xmx 来指定最大堆大小)或者系统属性 ( 使用 -D 给出系统属性 )。如下图所示,当前作业的虚拟机参数就是 4 个系统属性。

图 4. 显示 JVM 参数
图 4. 显示 JVM 参数

WRKJVMJOB 选项 2 和 3 分别列出系统的环境变量和 PASE(IBM i 中类似于 AIX 的运行环境)的环境变量。下图就是选项 3 的一个输出窗口的一部分。

图 5. 显示 PASE 环境变量
显示 PASE 环境变量

此处我们可以看到 PASE_LANG,HOME,QIBM_IFS_OPEN_MAX 等等的环境变量的值。具体这些环境变量的含义超出了本文的介绍范围。

WRKJVMJOB 选项 4,java 锁的信息。这个选项是用来查看作业中每个线程的锁信息,一般情况下此窗口中看不到锁的存在,或者有锁,但是很快就释放了。

图 6. 显示 Java 锁信息
图 6. 显示 Java 锁信息

有时如果作业比较繁忙的情况下我们可以看到一些锁信息,并且这个锁会很频繁的变化。下图就是一个锁的信息,( 为节省篇幅 , 后面的图片我将尽量省掉通用的头部 ) 我们可以看到,线程 00000A69 在等待对象 31083108.

图 7. 线程等待的对象锁
图 7. 线程等待的对象锁

用 5 选项在这个对象上时,你会发现对象 31083108 上的等待线程只有 00000A69

图 8. 某个对象锁上等待的线程
图 8. 某个对象锁上等待的线程

当发现某个作业不再响应用户请求,并且不占用任何 CPU 时间的情况下,可以认为死锁是一种可能。比如下面的这个例子,使用 WRKJVMJOB 的 Java 锁选项可以很容易的发现一个死锁的存在:线程 00000074 拿到了(HELD)对象 74107410 的锁,但是等待(WAIT)在了对象 74147414 上。而线程 00000075 拿到了对象 74147414 的锁,但是却等待在了对象 74107410 上。

图 9. 死锁现象
图 9. 死锁现象

分别使用选项 5 去查看 74107410 和 74147414 对象的锁,我们也可以注意到这个死锁的存在。74107410 对象被 00000074 线程得到(HELD),但是却阻塞了线程 00000075. 对象 74147414 也存在类似的现象。

图 10. 等待在死锁对象上的线程列表(一)
图 10. 等待在死锁对象上的线程列表(一)
图 11. 等待在死锁对象上的线程列表(二)
图 11. 等待在死锁对象上的线程列表(二)

WRKJVMJOB 选项 5,垃圾回收信息。垃圾回收其实是 java 虚拟机中的内存管理模块。此处显示的垃圾回收信息也是与内存相关的。

图 12. 垃圾回收信息(一)
图 12. 垃圾回收信息(一)

此处给出了当前 J9 作业的堆的信息 , 包括初始堆大小 , 最大堆大小 , 当前堆大小 , 以及正在被使用的堆的大小等等。

图 13. 垃圾回收信息(二)
图 13. 垃圾回收信息(二)

在这一页中显示了垃圾回收的的一些一般信息,比如当前垃圾回收的周期数,垃圾回收策略类型等等。

这个选项所列出的信息中, 当前堆大小经常被用来检测一个应用所能使用或者分配的堆的当前值。在一个应用程序的运行周期中此值的变化情况可以用来修正 JVM 的参数,以求获得最佳的应用性能。同时这个值与最大堆大小的比较也能发现最大堆大小的设置情况是否合理。这些都经常被用于分析系统内存不足造成的程序崩溃。

WRKJVMJOB 选项 6 和 7。他们将分别列出当前作业的初始系统属性和当前系统属性。我们拿选项 7 的输出为例进行讲解。选项 7 是作业的当前系统属性。

图 14. 当前作业的系统属性(部分)
图 14. 当前作业的系统属性(部分)

这一页属性值中包含两个值得一提的属性,一个是 java.home, 一个是 java.version. java.home 是用来指明当前 JDK 目录的。检查这个属性的值可以使我们获得当前作业的准确的目录。通常这个属性值是通过获取 JAVA_HOME 环境变量的值来实现的。也就是说,J9 的应用程序可以通过这个环境变量的值来选择使用哪个类型的 JDK。另外一个有趣的属性是 java.version。熟悉 Classic JVM(IBM i 上早期出现的一种类型的 JDK)的朋友对这个属性很熟悉,它在 Classic JVM 世界里是用来选择使用什么版本的 JDK 的。然而对于 J9 来讲这个属性是一个只读的,我们不再通过设置这个属性的值来选择不同的 JDK,而是要使用 JAVA_HOME 这个环境变量。虽然此处没有列出更多的属性页来,但是在众多的属性中还有很多有意思的属性,可以帮助我们分析和解决问题。比如属性 java.class.path,这个属性是用来指明用户类的搜索路径的。这个属性值得正确性将直接影响应用程序是否能正常运行。还有很多其他的属性,具体可以查阅参考【 3 】 IBM i 信息中心

选项 6 与 7 的不同就在于,选项 6 中的属性值是作业启动时的属性值。这个选项中列出的属性主要用于检查作业提交时是否给出了正确的属性值。

WRKJVMJOB 选项 8,java 线程。这个选项经常被用来分析实际问题。首先,从字面上就可以知道,它用于显示当前作业的所有线程。

图 15. 显示作业的线程
图 15. 显示作业的线程

此处列出的线程信息中,标识,名称和状态经常被使用。如果要处理 CPU 或者 I/O 等相关问题,后两列就会发挥作用。此处功能键 F11 是可以帮我们现行线程的更多信息。比如 PASE 线程标示 ,Java 线程状态等等。这个 PASE 线程标示主要用于跟其他的 java 作业分析工具中的输出进行比对的。通过它我们可以准确找到在其他输出中的与该线程相关的信息。 比如 processinfo 宏的输出,我们会在后面进行更详细的介绍。

在此使用选项 10 来查看选中线程的栈情况。这是分析实际问题的强有力的手段。比如下面的这个窗口就显示了一个线程的栈:此处,笔者并不是要读者去读懂栈中的每个信息,但是希望能通过这个例子来说明栈中的大概信息。比如最左列中的类型,这一列中我们会发现有“”(空白),“P”,“J”等类型。他们分别表示 ILE 模块栈,PASE 栈以及 java 代码栈。用以说明后面的栈项是来自于什么部分的代码。第二,三和四列则更详细说明了每个栈项具体信息。比如 java 代码中的 com/ibm/misc/SignalDi* 类的 waitForSignal 方法等等。通过这些信息,我们可以大概看出当前线程停在什么地方,或者停在哪个模块里面。当然在解决一个实际问题时,往往会根据更多的信息进行判断,此处仅仅是给出了一个线程的 ILE/PASE/Java 的栈信息。

图 16 某线程的栈信息
图 16 某线程的栈信息

WRKJVMJOB 选项 10 是用来显示更详细垃圾回收周期信息的。我们最经常使用的就是最大次数和每一次的执行时间。最大次数可以用来查看是不是有过多的 GC,过多的 GC 通常表明堆大小的设置存在问题;而每一次的执行时间可以用来查看 GC 是不是影响性能的因素。

选项 30,31,32 是经常实际使用的。如果你发现 java 的作业工作不正常了,如果不是崩溃,这几个选项都可以被用来产生一些非常有用的分析数据。他们分别是堆 dump,系统 dump,java dump。对于这几个 dump 的具体介绍,肯定无法在这个文章中进行详述。但是有一点也许能够帮助到大家,那就是这些 J9 作业的 dump 是跟其他平台上特别是 AIX 上完全通用的。我们可以使用任何 j9 的 dump 分析的工具来分析这些 dump 文件。

WRKJVMJOB 选项 40,41 主要是用来实现实时的 verbosegc 的功能。通过实时的打开或关闭 verbosegc 的选项,来获得或结束 verbosegc 的输出。Verbosegc 是 J9 的一个选项可以用来输出非常详细的垃圾回收周期的信息。具体 verbosegc 的详细说明请查阅【 4 】每一个 JDK 的 <<J9 诊断 >>


GENJVMDMP 以及 PRTJVMJOB 工具

有了对 WRKJVMJOB 的了解,这两个工具相比而言是比较简单的。首先,GENJVMDMP,这个工具主要是可以直接使某个作业产生 WRKJVMJOB 中 30,31,32 选项所产生的 dump 文件。 下面结合具体示例来讲解该工具的使用。首先看看 GENJVMDMP 的选项:

图 17. GENJVMDMP 命令参数
图 17 GENJVMDMP 命令参数

在此命令选项中,我们可以看到作业名称,用户名,以及作业标示可以用来确定唯一一个作业,而 dump 类型,此处则可以选择一个或者多个。他们分别是 java dump,系统 dump,以及堆 dump。我们选择系统中的一个 java 作业,并产生默认的 *JAVA dump 如下:

GENJVMDMP JOB(044210/QSYS/QSVRMSERMD)

可以通过 WRKJVMJOB 中的选项 9,来查看这个作业的日志如下:从这个日志中,可以清楚的看到,产生的 java dump 被写入文件 javacore.20121027.081346.17.006.txt。这个文件就是一个标准的 java dump。从这个文件可以看到这个 J9 作业的详细参数,环境变量,系统信息,所有线程的 java 栈,锁等等的信息。

图 18. 作业日志
图 18 作业日志

当然用这个工具产生其他 dump 的过程跟这个是完全一致的。

另外一个工具是 PRTJVMJOB,这个工具主要的功能就是将某个特定作业的单个或者所有的选项用 *PRINT 的方式写入 spool 文件。其中可以用于打印的选项中有环境变量,线程,锁,垃圾回收等信息。其内容基本与 WRKJVMJOB 中的各个选项相同。


STRSST 中相关宏

除了以上 WRKJVMJOB,PRTJVMJOB,GENJVMDMP 三个工具外, 有时还要借助 STRSST 工具中提供的一些宏来完成对 J9 作业的分析。选项 141214 可以使我们跳转到高级分析窗口如下:

图 19. 高级分析窗口
图 19 高级分析窗口

这个窗口提供的众多宏中,有两个是经常用来分析 J9 作业的。他们是 jvminfo 以及 processinfo。Jvminfo 可以被用来列举出系统中所有 J9 作业信息。我们首先看一下 jvminfo 的帮助,我们选择 jvminfo,并给出“-h”作为参数。这个方法可以显示出 jvminfo 的说有帮助信息。一般我们使用 jvminfo 首先不带任何参数,或者 -dmpJVMs。这个命令用来产生 JVM 列表,从这个列表中我们可以找到进程一个任务编号 (Task),这个值我们主要用于后面的 processinfo 宏中用于选择某个作业。下面是 jvminfo 宏的一个输出结果。

图 20. jvminfo 输出
图 20 jvminfo 输出

使用这个任务编号(B000300002E81000),作为 processinfo 的参数,我们可以得到这个作业的进程信息。下面 processinfo 宏使用这个任务编号作为参数产生的输出中的前部。

图 21. processinfo 部分输出
图 21 processinfo 部分输出

这个输出中包括当前作业的所有线程信息,以及这些线程的栈信息。这个栈信息包括两部分的栈,一部分是 ILE 的栈,还有一部分就是 PASE 的栈,注意此处没有 java 栈。如果我们遇到的是作业挂起,没有任何响应,不占用任何 CPU,并且 java 部分没有明显的挂起问题。这是 processinfo 的输出就是必要的。通过分析 procesinfo 输出中的 PASE 栈,往往可以看到一些有价值的信息。如果作业没有任何响应并且在占用比较高的 CPU 利用率。这时定期的得到多次 processinfo 的输出,是帮助我们分析问题的有力做法。他通常都能给出占用高 CPU 的代码段,然后进行进一步的分析。


总结

本文通过对 IBMi 提供的 J9 工具以及几个分析宏的介绍,简要总结了一些笔者在实际的工作中遇到的一些常用问题以及如何使用这些宏和工具去分析和解决这些问题。 希望能最终帮到读者。

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=IBM i
ArticleID=856848
ArticleTitle=IBM i 上 Java 分析工具的介绍
publish-date=01312013