Getting the parameters of a running JVM
JavaJvmJava Problem Overview
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.
Java Solutions
Solution 1 - Java
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
Solution 2 - Java
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.
Solution 3 - Java
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"
Solution 4 - Java
Alternatively, you can use jinfo
jinfo -flags <vmid>
jinfo -sysprops <vmid>
Solution 5 - Java
If you can do this in Java, try:
Example:
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
List<String> jvmArgs = runtimeMXBean.getInputArguments();
for (String arg : jvmArgs) {
System.out.println(arg);
}
Solution 6 - Java
On Linux, you can run this command and see the result:
ps aux | grep "java"
Solution 7 - Java
JConsole can do it. Also you can use the powerful Java VisualVM tool, which also is included in JDK since 1.6.0.8.
Solution 8 - Java
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).
Solution 9 - Java
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.
Solution 10 - Java
You can use the JConsole command (or any other JMX client) to access that information.
Solution 11 - Java
This technique applies for any Java applications running local or remote.
- Start your Java application.
- Run Java VisualVM found in you JDK (such as C:\Program Files\Java\jdk1.8.0_05\bin\jvisualvm.exe).
- When this useful tool starts look at the list of running Java applications under the "Local" tree node.
- Double click [your application] (pid [n]).
- 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.
Solution 12 - Java
_JAVA_OPTIONS is an environment variable that can be expanded:
echo $_JAVA_OPTIONS
Solution 13 - Java
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
.