`
wbj0110
  • 浏览: 1603900 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

Java process monitoring with the JDK's built-in profilers

阅读更多

Full-featured, built-in profilers like JConsole and VisualVM sometimes cost more than they're worth in performance overhead — particularly in systems running on production hardware. So, in this second article focusing on Java performance monitoring, I'll introduce five command-line profiling tools that enable developers to focus on just one aspect of a running Java process.

The JDK includes many command-line utilities that can be used to monitor and manage Java application performance. Although most of them are labeled "experimental" and therefore technically unsupported, they're still useful. Some might even be seed material for special-purpose tools that could be built using JVMTI or JDI (see Resources).

1. jps (sun.tools.jps)

Develop skills on this topic

This content is part of progressive knowledge paths for advancing your skills. See:

Many command-line tools require that you identify the Java process that you want to monitor. This isn't so different from similar tools that monitor native-operating-system processes and also require a process identifier to work.

The "VMID" identifier is not always the same as the native operating system process identifier ("pid"), which is why we need the JDK's jps utility.

Using jps within a Java process

As with most of the tools shipped with the JDK, and all of the tools mentioned in this article, the jpsexecutable is actually a thin wrapper around the Java class or set of classes that carry out the vast majority of the work. Under Windows®, the tools are .exe files that use the JNI Invocation API to call directly to the class in question; under UNIX®, most of the tools are symbolic links to a shell script that kicks off a generic Java launcher with the right class name specified.

If you want to use jps's (or any other tool's) functionality from within a Java process — such as an Ant script — it's relatively easy to just call main() on the class that is the "main" class for each tool. For easy reference, that class name appears in parentheses after each tool's name.

jps— whose name reflects the ps utility found on most UNIX systems — tells us the JVMID of a running Java application. As its name implies, jps returns the VMIDs for all discoverable Java processes running on a given machine. If jps doesn't discover a process, it doesn't mean that the Java process can't be attached or spelunked. It just means that it isn't advertising itself as available.

If the Java process can be found, jps will list the command-line used to launch it. This way of differentiating between Java processes is important because, as far as the operating system is concerned, all Java programs are "java." For most purposes, the VMID is the important number to note.

Getting started with profilers

The easiest way to get started with profiling utilities is to use a demo program like the SwingSet2 demo found at demo/jfc/SwingSet2. Doing this avoids potential hangups with processes running as background/daemon processes. Once you're familiar with the tool and its overhead, you can try it on your actual programs.

After you load up your demo app, run jps and note the returned vmid. For best effect, launch the Java program with the -Dcom.sun.management.jmxremote property set. If you don't use this setting, some data gathered by some of the tools below will be unavailable.

 

2. jstat (sun.tools.jstat)

The jstat utility can be used to gather a variety of different statistics. jstat statistics are sorted into "options" that are specified at the command-line as the first parameter. As of JDK 1.6, you can view the list of options available by running jstat with the command -options. Some options are shown in Listing 1:

Listing 1. jstat options
-class
-compiler
-gc
-gccapacity
-gccause
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcpermcapacity
-gcutil
-printcompilation

The utility's JDK documentation (see Resources) will tell you what each of the options in Listing 1 returns, but the majority of them are used to gather performance information about the garbage collector, or just parts of it. The -class option reveals loaded and unloaded classes (making it a great utility for detecting ClassLoader leaks within the app server or your code), and both -compiler and -printcompilation display information about the Hotspot JIT compiler.

By default, jstat will display the information at the moment you check it. If you want snapshots taken at regular intervals, specify the intervals in milliseconds following the -options command. jstat will continuously display snapshots of the monitored process's information. If you wantjstat to take a specific number of snapshots before terminating, specify that number after the interval/period value.

If 5756 were the VMID for a running SwingSet2 process started a few minutes ago, then the following command would tell jstat to produce a gc snapshot dump every 250 milliseconds for 10 iterations, then quit:

jstat -gc 5756 250 10

Note that Sun (now Oracle) reserved the right to change the output of the various options, or even the options themselves, without warning. That's the downside of using unsupported utilities. See the Javadocs for complete details about each of the columns in the jstat output.

 

3. jstack (sun.tools.jstack)

Knowing what's happening inside of a Java process vis-a-vis the executing threads is a common diagnostic challenge. For example, when an application has suddenly stopped processing, it's obvious that some kind of starvation has been reached, but it isn't obvious just by looking at the code where the starvation has occurred, or why.

jstack is a utility that returns a complete dump of the various threads running in an app, which you can then use to pinpoint the problem.

Running jstack with the VMID of the desired process will generate a stack dump. In this regard, jstack works the same as pressing Ctrl-Break within the console window in which a Java program is running, or calling Thread.getAllStackTraces() or Thread.dumpStack() on each of theThread objects in the VM. A jstack call also dumps information about non-Java threads running within the VM, which aren't always available asThread objects.

jstack's -l parameter offers up a slightly longer dump that includes more detailed information about the locks held by each of the Java threads, and can thus be invaluable in finding (and squashing!) deadlock or scalability bugs.

 

4. jmap (sun.tools.jmap)

Sometimes, the problem you're dealing with is an object leak, such as an ArrayList (which could hold thousands of objects) that just isn't getting released when it should. Another problem that is more general would be an expanding heap that never seems to shrink, despite active garbage collection.

When you're trying to locate an object leak, it's incredibly helpful to take a picture of the heap at a given moment in time, and then look through what's there. jmap provides the first part of that functionality by taking a snapshot picture of the heap. You can then analyze the heap data using the jhat utility described in the next section.

Using jmap is straightforward, like all the other utilities described here. Simply point jmap at the VMID of the Java process you want to snapshot, and give it some parameters to describe the resulting file produced. The options you'll pass to jmap consist of the name of the file to dump to and whether to use a text file or binary file. A binary file is the most useful option, but only when combined with some kind of indexing tool — manually slogging through several megabytes of text filled with hexadecimal values is not the best way to spend your day.

For a more casual glance at the Java heap, jmap also supports a -histo option. -histo produces a text histogram of the objects currently strongly referenced in the heap, sorted by the total number of bytes consumed by that particular type. It also gives the total number of instances of that particular type, which allows for some primitive calculations and guesses about relative cost per instance.

Unfortunately, jmap doesn't have a period-and-max-count option like jstat does, but it's relatively easy to put calls to jmap (or to jmap.main()) into a loop in either a shell script or other class to take snapshots periodically. (In fact, this would be a good extension to add to jmap, either as a source patch to the OpenJDK itself or as an extension to another utility.)

 

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

Once you've dumped the heap into a binary file, you can use jhat to analyze the binary heap dump file. jhat creates an HTTP/HTML server that can be surfed in a browser, giving an object-by-object view of the heap, frozen in time. While it could be amusing to walk through the heap, object reference by object reference, you're probably better served by doing some kind of automated analysis of the whole mess. Fortunately, jhatsupports an OQL syntax for doing that analysis.

For example, running an OQL query for all Strings with more than 100 characters would look like this:

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

The results are displayed as links to the objects, which then display the complete contents of that object, the field references to other objects as additional links that can be dereferenced. OQL queries can also invoke methods on the objects themselves, use regular expressions as part of the query, and use built-in query tools. One query tool, the referrers() function, displays all the referrers that refer to an object of a given type. Here's the query to find all the referrers to File objects:

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

You can find the full syntax of OQL and its features under the "OQL Help" page inside the jhat browser environment. Combining jhat with OQL is a powerful way to do a targeted investigation of a misbehaving heap.

 

In conclusion

The JDK's profiling extensions can be very useful when you need to get a closer look at what's going on inside a Java process. All of the tools introduced in this article can be used by themselves from the command line. They also can be powerfully combined with JConsole or VisualVM. Whereas JConsole and VisualVM provide an overarching view of the Java virtual machine, specifically focused tools like jstat and jmap let you fine-tune your investigation.

分享到:
评论

相关推荐

    APRESS--Logging-in-Java-with-the-JDK-1_4-Logging-API-and-Apache-log4j

    APRESS--Logging-in-Java-with-the-JDK-1_4-Logging-API-and-Apache-log4j

    java-jdk1.8-8u361-all-jdk-win-linux

    java-jdk1.8-8u361-all-jdk-win-linux 该压缩包中包含jdk1.8-8u361下windows版本和linux版本,其包含快速安装包和对应的jdk压缩包版本,具体内容如下: jdk-8u361-linux-aarch64.rpm jdk-8u361-linux-i586.rpm jdk-8...

    bcprov-ext-jdk15on-152和bcprov-jdk15on-152

    标题中的"bcprov-ext-jdk15on-152"和"bcprov-jdk15on-152"是两个与Bouncy Castle库相关的Java档案文件,它们主要用于提供加密和安全服务。Bouncy Castle是一个开源的Java安全提供者,广泛用于密码学应用,包括加密、...

    bcprov-jdk15on-1.54.jar bcprov-ext-jdk15on-1.54.jar下载

    2.将下载的两个JAR文件复制到:JDK安装目录\jre\lib\ext下,例如我的就是D:\Program Files (x86)\java\JDK1.6\jre\lib\ext 3.打开java.security文件:在JDK安装目录\jre\lib\security下的java.security文件。

    bcprov-ext-jdk15on-1.54.jar,bcprov-jdk15on-1.54.jar

    在Java开发过程中,有时会遇到一个异常:“java.lang.RuntimeException: Could not generate DH keypair”。这个异常通常是由于Java加密库的问题导致的,特别是在进行安全通信,如使用SSL/TLS协议时,系统尝试生成...

    bcprov-jdk15on-1.64.jar

    ECC 加密工具jar包 bcprov-jdk15on-1.64.jarbcprov-jdk15on-1.64.jarbcprov-jdk15on-1.64.jarbcprov-jdk15on-1.64.jarbcprov-jdk15on-1.64.jar

    bcprov-ext-jdk15on-1.52和bcprov-jdk15on-1.52

    标题中的"bcprov-ext-jdk15on-1.52"和"bcprov-jdk15on-1.52"是两个不同版本的Java软件包,它们都是由The Legion of the Bouncy Castle(Bouncy Castle)组织提供的加密库。Bouncy Castle是一个广泛使用的开源Java...

    bcprov-ext-jdk15on-1.52.jar和bcprov-jdk15on-1.52.jar

    标题中的"bcprov-ext-jdk15on-1.52.jar"和"bcprov-jdk15on-1.52.jar"是两个与Java相关的库文件,它们都属于Bouncy Castle加密库的不同版本。Bouncy Castle是一个开源的Java安全套件,提供广泛的安全服务,包括加密、...

    bcprov-jdk15on-1.64运行包及源码.zip

    标题中的"bcprov-jdk15on-1.64运行包及源码.zip"指的是Bouncy Castle Provider的Java版本1.64的运行时库和源代码压缩包。Bouncy Castle是一个开源的Java安全库,它提供了加密、数字签名、PKI(公钥基础设施)以及SSL...

    bcprov-ext-jdk15on-154.jar和bcprov-jdk15on-154.jar

    "bcprov-ext-jdk15on-154.jar" 和 "bcprov-jdk15on-154.jar" 是两个非常重要的工具jar包,它们属于Bouncy Castle加密库,专门用于解决Java中的加密和安全问题,尤其是当系统遇到"javax.net.ssl.SSLException: java....

    bcprov-ext-jdk15on-1.54.jar和bcprov-jdk15on-1.54.jar压缩文件

    《深入解析bcprov-jdk15on与bcprov-ext-jdk15on:Java加密库的秘密武器》 在Java开发中,加密技术是至关重要的,它保障了数据的安全传输和存储。bcprov-jdk15on和bcprov-ext-jdk15on是Bouncy Castle项目提供的两个...

    java-jdk1.7-jdk-7u80-windows-x64.zip

    安装Java JDK 1.7 on Windows x64的步骤非常简单,只需双击下载的“jdk-7u80-windows-x64.exe”文件,然后按照安装向导进行操作。安装过程中,记得选择合适的安装路径,并勾选“添加Java到系统环境变量”选项,以便...

    bcpkix-jdk15on-1.59.jar

    org/bouncycastle/jce/provider/BouncyCastleProvider bcpkix-jdk15on 需要 bcpkix-jdk15on-1.59 和 bcprov-jdk15on-1.59 才能匹配

    jdk11(jdk-11.0.19-windows-x64-bin.exe)

    标题中的"jdk11(jdk-11.0.19-windows-x64-bin.exe)"指的是Java Development Kit的第11个主要版本,具体是11.0.19更新,针对Windows操作系统的64位版本的二进制安装包。JDK是Java编程语言的核心组件,包含了开发和...

    bcmail-jdk15on-1.49.jar/bcpkix-jdk15on-1.49.jar/bcprov-jdk15on-1.49.jar打包下载

    这些文件是Bouncy Castle库的不同组件,用于Java平台上的加密和数字签名操作。Bouncy Castle是一个广泛使用的开源Java安全API,提供了对加密算法、PKI(公钥基础设施)、CMS(内容完整性服务)以及SSL/TLS的支持。这...

    bcprov-ext-jdk15on-149,bcprov-jdk15on-149

    标题中的"bcprov-ext-jdk15on-149"和"bcprov-jdk15on-149"是两个与Java相关的库文件,它们属于Bouncy Castle项目,这是一个广泛使用的开源加密库,特别适用于Java平台。Bouncy Castle提供了大量的加密算法,包括对称...

    jdk-7-ea-bin-b24-windows-i586-04_dec_2007

    标题“jdk-7-ea-bin-b24-windows-i586-04_dec_2007”指的是Java Development Kit(JDK)的早期访问版本7的二进制发行版,构建号为b24,专为32位的Windows操作系统设计。这个版本发布于2007年12月4日,是Java开发工具...

    Java-JDK1.8-windows-x64位

    Java-JDK1.8-windows-x64位——免费不要积分!!! Java-JDK1.8-windows-x64位——免费不要积分!!! Java-JDK1.8-windows-x64位——免费不要积分!!! Java-JDK1.8-windows-x64位——免费不要积分!!! Java-JDK...

    bcprov-jdk15on-158.jar

    标题中的"bcprov-jdk15on-158.jar"是一个Java的库文件,它属于Bouncy Castle项目,这是一个广泛使用的加密库,为Java平台提供了强大的加密功能。Bouncy Castle提供了许多安全服务,包括加密算法、数字签名、证书处理...

    bcprov-ext-jdk15on-159.jar

    bcprov-ext-jdk15on-159.jar官网下载最新版本,用它实现RSA nopadding。

Global site tag (gtag.js) - Google Analytics