Getting the parameters of a running JVM

Is there a way to get the parameters of a running JVM?

Is there a command-line tool, like jstat, which takes as input the PID of the JVM and returns its starting parameters? I am particularly interested in the -Xmx and -Xms values that were given when starting the JVM.

To clarify my constraints for the JVM, we would like to check if it is running on a production server. That's why we prefer the minimum disruption. We are able to monitor the JVM using jstat, and so we hope there's a similar simple solution to access the parameters.

We also tried to get the parameters using jvisualvm. But in order to connect to a remote jvm, we need to run jstatd and modify the security settings of the JVM, which we found to be very disruptive and risky on a production server.

176201 次浏览

JConsole can do it. Also you can use the powerful Java VisualVM tool, which also is included in JDK since 1.6.0.8.

If you can do this in Java, try:

RuntimeMXBean

ManagementFactory

Example:

RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
List<String> jvmArgs = runtimeMXBean.getInputArguments();
for (String arg : jvmArgs) {
System.out.println(arg);
}

You can use jps like:

jps -lvm

It prints something like:

4050 com.intellij.idea.Main -Xms128m -Xmx512m -XX:MaxPermSize=250m -ea -Xbootclasspath/a:../lib/boot.jar -Djb.restart.code=88
4667 sun.tools.jps.Jps -lvm -Dapplication.home=/opt/java/jdk1.6.0_22 -Xms8m

You can use the JConsole command (or any other JMX client) to access that information.

Alternatively, you can use jinfo

jinfo -flags <vmid>
jinfo -sysprops <vmid>

This technique applies for any Java applications running local or remote.

  1. Start your Java application.
  2. Run Java VisualVM found in you JDK (such as C:\Program Files\Java\jdk1.8.0_05\bin\jvisualvm.exe).
  3. When this useful tool starts look at the list of running Java applications under the "Local" tree node.
  4. Double click [your application] (pid [n]).
  5. On the right side, there will be inspection contents in a tab for the application. In the middle of the Overview tab, you will see the JVM arguments for the application.

Java VisualVM can be found in any JDK since JDK 6 Update 7. Video tutorial on Java VisualVM is here.

On Linux:

java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'

On Mac OS X:

java -XX:+PrintFlagsFinal -version | grep -iE 'heapsize|permsize|threadstacksize'

On Windows:

java -XX:+PrintFlagsFinal -version | findstr /i "HeapSize PermSize ThreadStackSize"

Source: Find out your Java heap memory size

As per JDK 8 documentation jcmd is the suggested approach.

It is suggested to use the latest utility, jcmd instead of the previous jstack, jinfo, and jmap utilities for enhanced diagnostics and reduced performance overhead.

Below are commands to get your properties/flags you want.

jcmd pid VM.system_properties
jcmd pid VM.flags

We need the PID. For this, use jcmd -l, like below

cd ~/javacode
jcmd -l


11441 Test
6294 Test
29197 jdk.jcmd/sun.tools.jcmd.JCmd -l

Now it is time to use these PIDs to get properties/flags you want.

Command: jcmd 11441 VM.system_properties

11441:
#Tue Oct 17 12:44:50 IST 2017
gopherProxySet=false
awt.toolkit=sun.lwawt.macosx.LWCToolkit
file.encoding.pkg=sun.io
java.specification.version=9
sun.cpu.isalist=
sun.jnu.encoding=UTF-8
java.class.path=.
java.vm.vendor=Oracle Corporation
sun.arch.data.model=64
java.vendor.url=http\://java.oracle.com/
user.timezone=Asia/Kolkata
java.vm.specification.version=9
os.name=Mac OS X
sun.java.launcher=SUN_STANDARD
user.country=US
sun.boot.library.path=/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/lib
sun.java.command=Test
http.nonProxyHosts=local|*.local|169.254/16|*.169.254/16
jdk.debug=release
sun.cpu.endian=little
user.home=/Users/XXXX
user.language=en
java.specification.vendor=Oracle Corporation
java.home=/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home
file.separator=/
java.vm.compressedOopsMode=Zero based
line.separator=\n
java.specification.name=Java Platform API Specification
java.vm.specification.vendor=Oracle Corporation
java.awt.graphicsenv=sun.awt.CGraphicsEnvironment
sun.management.compiler=HotSpot 64-Bit Tiered Compilers
ftp.nonProxyHosts=local|*.local|169.254/16|*.169.254/16
java.runtime.version=9+181
user.name=XXXX
path.separator=\:
os.version=10.12.6
java.runtime.name=Java(TM) SE Runtime Environment
file.encoding=UTF-8
java.vm.name=Java HotSpot(TM) 64-Bit Server VM
java.vendor.url.bug=http\://bugreport.java.com/bugreport/
java.io.tmpdir=/var/folders/dm/gd6lc90d0hg220lzw_m7krr00000gn/T/
java.version=9
user.dir=/Users/XXXX/javacode
os.arch=x86_64
java.vm.specification.name=Java Virtual Machine Specification
java.awt.printerjob=sun.lwawt.macosx.CPrinterJob
sun.os.patch.level=unknown
MyParam=2
java.library.path=/Users/XXXX/Library/Java/Extensions\:/Library/Java/Extensions\:/Network/Library/Java/Extensions\:/System/Library/Java/Extensions\:/usr/lib/java\:.
java.vm.info=mixed mode
java.vendor=Oracle Corporation
java.vm.version=9+181
sun.io.unicode.encoding=UnicodeBig
java.class.version=53.0
socksNonProxyHosts=local|*.local|169.254/16|*.169.254/16

Command: jcmd 11441 VM.flags output:

11441:
-XX:CICompilerCount=3 -XX:ConcGCThreads=1 -XX:G1ConcRefinementThreads=4 -XX:G1HeapRegionSize=1048576 -XX:InitialHeapSize=67108864 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=1073741824 -XX:MaxNewSize=643825664 -XX:MinHeapDeltaBytes=1048576 -XX:NonNMethodCodeHeapSize=5830092 -XX:NonProfiledCodeHeapSize=122914074 -XX:ProfiledCodeHeapSize=122914074 -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:-UseAOT -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseG1GC

For more instructions of usages of jcmd, see my blog post.

Windows 10 or Windows Server 2016 provide such information in their standard Task Manager.

It is a rare case for production, but if the target JVM is running on Windows, the simplest way to see its parameters is to press Ctrl + Alt + Delete, choose the Processes tab and add the Command line column (by clicking the right mouse button on any existing column header).

If you are interested in getting the JVM parameters of a running Java process, then just do kill -3 java-pid.

You will get a core dump file in which you can find the JVM parameters used while launching the Java application.

On Linux, you can run this command and see the result:

ps aux | grep "java"

_JAVA_OPTIONS is an environment variable that can be expanded:

echo $_JAVA_OPTIONS

In case of really small containers (no ps, tree, jcmd etc.) you can also try to guess process id (by listing ls -l /proc) and then read parameters from specific process: cat /proc/<pid>/cmdline.

example:

$ cat /proc/614/cmdline

may print something like:

java-D[Standalone]-server-Xms64m-Xmx512m-XX:MetaspaceSize=96M-XX:MaxMetaspaceSize=256m-Djava.net.preferIPv4Stack=true-Djboss.modules.system.pkgs=org.jboss.byteman-Djava.awt.headless=true-Dkeycloak.profile=preview-Djboss.as.management.blocking.timeout=1800-Djboss.node.name=keycloak1loak/modulesorg.jboss.as.standalone

To read the same for all processes (discarding any permission errors and processes that dissapeared during command execution):

for i in $(find /proc/ -maxdepth 2 -type f -name cmdline -exec ls {} 2>/dev/null \; ); do echo "$i"; cat $i 2>/dev/null; echo; echo; done

Note: It's not narrowed down to java processes only - you can do that using grep.

I usually do ps -ef | grep java. It outputs the process with PID + the used command line parameters.