Sunday, August 12, 2012

How to See a Long Command Line of a Running Process on HotSpot VM

To find the command line of a running Java process, you can use the following different approaches[1]:
  1. ps -ef | grep java
  2. cat /proc/<pid>/cmdline
  3. jps -vl | grep
However, as you may soon find out, the displayed command line got truncated in the output.  For example, using my Linux system, the maximum lengths of a command line displayed using the above approaches are:
  1. 4096
  2. 4029
  3. 1024
Unfortunately, my original command line is 7972 characters long.  So, none of the above approaches help.

jinfo & jrcmd

If you are using HotSpot VM, there is one command that can help:
  • jinfo
To run it, you provide the process ID as its argument:

$jinfo 26467
Attaching to process ID 26467, please wait...
WARNING: Hotspot VM version 23.0-b21-internal does not match with SA version 23.0-b18. You may see unexpected results.
Debugger attached successfully.
Server compiler detected.
JVM version is 23.0-b21-internal

In its standard output, it displays VM Flags at the end.

VM Flags:

-XX:MaxPermSize=512m -Xmx4g -Xms128m -verbose:class -XX:-UseCompressedStrings -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xms4096m -Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/u01/rup1/instance/debug -Dweblogic.Name=SalesServer_1 -Djava.security.policy=/mnt/rup1/crm1/appltop/rup1/fusionapps/wlserver_10.3/server/lib/weblogic.policy -Dweblogic.ProductionModeEnabled=true -Dweblogic.system.BootIdentityFile=/c1/mt/rup1/instance/domains/mt1.crm1.rup1.psr.oracle.com/CRMDomain/servers/SalesServer_1/data/nodemanager/boot.properties -Dweblogic.nodemanager.ServiceEnabled=true -Dweblogic.security.SSL.ignoreHostnameVerification=true -Dweblogic.Reverse
...

If you're using JRockit, there is a similar command that you can use:

$jrcmd  20507 command_line
20507:
Command Line: -Xmx4g -Xms128m -Xms4096m -Xmx4096m -Xgc:genpar -XX:+HeapDumpOnOutOfMemoryError...

java.lang.RuntimeException

Note that you need to make sure that the jinfo you are running is the same JVM install as what your Java program is running.  If you don't, you may see the following RuntimeException:

$ jinfo 26467
Attaching to process ID 26467, please wait...
Exception in thread "main" java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:616)
        at sun.tools.jinfo.JInfo.runTool(JInfo.java:97)
        at sun.tools.jinfo.JInfo.main(JInfo.java:71)
Caused by: java.lang.RuntimeException: Type "nmethodBucket*", referenced in VMStructs::localHotSpotVMStructs in the remote VM, was not present in the remote VMStructs::localHotSpotVMTypes table (should have been caught in the debug build of that VM). Can not continue.
        at sun.jvm.hotspot.HotSpotTypeDataBase.lookupOrFail(HotSpotTypeDataBase.java:361)
        at sun.jvm.hotspot.HotSpotTypeDataBase.readVMStructs(HotSpotTypeDataBase.java:252)
        at sun.jvm.hotspot.HotSpotTypeDataBase.(HotSpotTypeDataBase.java:87)
        at sun.jvm.hotspot.bugspot.BugSpotAgent.setupVM(BugSpotAgent.java:568)
        at sun.jvm.hotspot.bugspot.BugSpotAgent.go(BugSpotAgent.java:494)
        at sun.jvm.hotspot.bugspot.BugSpotAgent.attach(BugSpotAgent.java:332)
        at sun.jvm.hotspot.tools.Tool.start(Tool.java:163)
        at sun.jvm.hotspot.tools.JInfo.main(JInfo.java:128)
        ... 6 more

To fix this, I have provided the full path of JDK was used to run my original Java program in the jinfo command line:
  • /c1/mt/rup1/xxxapps/HS/bin/jinfo  26467

References