What are my command-line flags, and the system properties for running Java process

This post explains how to use OpenJDK CLI utility jinfo

Posted by Vipin Sharma on Friday, May 28, 2021 Tags: OpenJDK tools   7 minute read

Imagine a situation when you observe a memory leak in production java application, and with increasing memory usages you know it can throw OutOfMemoryError in some time. You have not set HeapDumpOnOutOfMemoryError and HeapDumpPath flags while starting the Java application. This being your production application, now you can not restart application immediately and set these flags. In such a situation jinfo can be great help, it can help us to set these flags for a running Java application. We will see this particular example later in the post. While troubleshooting production Java application often we need to check command line flags passed to JVM, arguments passed to the main function, and system properties. jinfo is a very helpful command to get this information.


Troubleshooting a Java Application with jinfo

In this section, we will see how to use jinfo with a running Java process.


Command structure

jinfo [option] pid

option: This represents the jinfo command-line options, we will how to use these options later in this post.
pid:    The process ID for which the configuration information is to be printed.


Java program we will be analyzing in this post

Following is Java class we will run to understand different features available in jinfo

public class Test
{
   public static void main(String[] args)
   {
      while(true)
      {
      }
   }
}

For all our examples we will be using Java 17, as of writing this post it is built using JDK master branch. This post can help you to build JDK from source.

We are running Java process using below command:

java -XX:ConcGCThreads=6 -Xmx256m -Xms8m -Xss256k -DTEST_ARGUMENT=1 Test argument1 argument2

This command prints java process ids, see this blog post to read more about jps.

jps -ml

Output:

10000 Test argument1 argument2
10071 jdk.jcmd/sun.tools.jcmd.JCmd -l

pid 10000 is the java process we will use in rest of the post.


jinfo help command

This is jinfo help command, it prints usage instructions and all the options available in jinfo

jinfo --help

Output of help command:

Usage:
jinfo <option> <pid>
(to connect to a running process)

where <option> is one of:
-flag <name>         to print the value of the named VM flag
-flag [+|-]<name>    to enable or disable the named VM flag
-flag <name>=<value> to set the named VM flag to the given value
-flags               to print VM flags
-sysprops            to print Java system properties
<no option>          to print both VM flags and system properties
-? | -h | --help | -help to print this help message


This command prints command-line flags passed to the JVM

jinfo -flags 10000

Output:

VM Flags:
-XX:CICompilerCount=12 -XX:ConcGCThreads=3 -XX:G1ConcRefinementThreads=13 -XX:G1HeapRegionSize=8388608 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=788529152 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=12616466432 -XX:MaxNewSize=7566524416 -XX:MinHeapDeltaBytes=8388608 -XX:MinHeapSize=8388608 -XX:NonNMethodCodeHeapSize=7602480 -XX:NonProfiledCodeHeapSize=122027880 -XX:ProfiledCodeHeapSize=122027880 -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:SoftMaxHeapSize=12616466432 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseG1GC


This command prints value of a particular flag UseG1GC:

jinfo -flag UseG1GC 10000

Output:

-XX:+UseG1GC

Another example to print flag CICompilerCount

jinfo -flag CICompilerCount 10000

Output:

-XX:CICompilerCount=12


This command prints system properties:

jinfo -sysprops 10000

Output:

Java System Properties:
#Sun Jun 27 11:02:17 IST 2021
java.specification.version=17
sun.management.compiler=HotSpot 64-Bit Tiered Compilers
sun.jnu.encoding=UTF-8
java.runtime.version=17-internal+0-adhoc.vipin.jdk
...
...


Printing all 3, system properties, VM flags, and VM arguments

This is jinfo command to print system properties, VM flags, and VM arguments:

jinfo 10000

Output:

Java System Properties:
#Sun Jun 27 11:02:17 IST 2021
java.specification.version=17
sun.management.compiler=HotSpot 64-Bit Tiered Compilers
sun.jnu.encoding=UTF-8
java.runtime.version=17-internal+0-adhoc.vipin.jdk
...

VM Flags:
-XX:CICompilerCount=12 -XX:ConcGCThreads=6 -XX:G1ConcRefinementThreads=13 -XX:G1HeapRegionSize=1048576 -XX:GCDrainStackTargetSize=64 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/vipin -XX:InitialHeapSize=8388608 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=268435456 -XX:MaxNewSize=160432128 -XX:MinHeapDeltaBytes=1048576 -XX:MinHeapSize=8388608 -XX:NonNMethodCodeHeapSize=7602480 -XX:NonProfiledCodeHeapSize=122027880 -XX:ProfiledCodeHeapSize=122027880 -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:SoftMaxHeapSize=268435456 -XX:ThreadStackSize=256 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseG1GC

VM Arguments:
jvm_args: -XX:ConcGCThreads=6 -Xmx256m -Xms8m -Xss256k -DTEST_ARGUMENT=1
java_command: Test argument1 argument2
java_class_path (initial): .
Launcher Type: SUN_STANDARD


Update manageable VM flags

jinfo can update manageable VM flags for a running Java application. While starting our Java application if we have not set HeapDumpOnOutOfMemoryError and HeapDumpPath flags, we can set these with jinfo.

This is the command to find all manageable flags, that can be updated for a running Java application.

jcmd 10000 VM.flags -all | grep manageable

Output:

uintx G1PeriodicGCInterval                    = 0                                      {manageable} {default}
double G1PeriodicGCSystemLoadThreshold        = 0.000000                               {manageable} {default}
bool HeapDumpAfterFullGC                      = false                                  {manageable} {default}
bool HeapDumpBeforeFullGC                     = false                                  {manageable} {default}
intx HeapDumpGzipLevel                        = 0                                      {manageable} {default}
bool HeapDumpOnOutOfMemoryError               = false                                  {manageable} {default}
ccstr HeapDumpPath                            =                                        {manageable} {default}
uintx MaxHeapFreeRatio                        = 70                                     {manageable} {default}
uintx MinHeapFreeRatio                        = 40                                     {manageable} {default}
bool PrintClassHistogram                      = false                                  {manageable} {default}
bool PrintConcurrentLocks                     = false                                  {manageable} {default}
bool ShowCodeDetailsInExceptionMessages       = true                                   {manageable} {default}
size_t SoftMaxHeapSize                        = 268435456                              {manageable} {ergonomic}

These are commands to update heap dump related flags:

jinfo -flag HeapDumpOnOutOfMemoryError=true 10000
jinfo -flag HeapDumpPath=/home/vipin 10000

Let’s check all flag values again, we can see HeapDumpOnOutOfMemoryError is true, and HeapDumpPath is set now.

$ jcmd 10000 VM.flags -all | grep manageable
uintx G1PeriodicGCInterval                      = 0                                      {manageable} {default}
double G1PeriodicGCSystemLoadThreshold          = 0.000000                               {manageable} {default}
bool HeapDumpAfterFullGC                        = false                                  {manageable} {default}
bool HeapDumpBeforeFullGC                       = false                                  {manageable} {default}
intx HeapDumpGzipLevel                          = 0                                      {manageable} {default}
bool HeapDumpOnOutOfMemoryError                 = true                                   {manageable} {default}
ccstr HeapDumpPath                              = /home/vipin                            {manageable} {attach}
uintx MaxHeapFreeRatio                          = 70                                     {manageable} {default}
uintx MinHeapFreeRatio                          = 40                                     {manageable} {default}
bool PrintClassHistogram                        = false                                  {manageable} {default}
bool PrintConcurrentLocks                       = false                                  {manageable} {default}
bool ShowCodeDetailsInExceptionMessages         = true                                   {manageable} {default}
size_t SoftMaxHeapSize                          = 268435456                              {manageable} {ergonomic}


Conclusion

jinfo is a very useful command to check VM flags, system properties and even we can set value of some VM flags. Utilities like this are very useful in a situation when we need to analyze and resolve problems in production Java application quickly. jinfo is part of JDK itself, no need to install any third party software.

If you want to get amazing Java jobs, I wrote an ebook 5 steps to Best Java Jobs. You can download this step-by-step guide for free!