Java Ergonomics and JVM Flags

Java Virtual Machine can tune itself depending on the environment and this smart tuning is referred to as Ergonomics.

When tuning Java, it's important to know which values were used as default for Garbage collector, Heap Sizes, Runtime Compiler by Java Ergonomics

There are many JVM command line flags. So, how do we find out which JVM flags are used? It turns out that JVM has flags to print flags. :)

I tested following commands with Java 8.

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 15.04
Release: 15.04
Codename: vivid
$ uname -a
Linux isurup-ThinkPad-T530 3.19.0-26-generic #28-Ubuntu SMP Tue Aug 11 14:16:32 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux



Printing Command Line Flags


We can use "-XX:+PrintCommandLineFlags" to print the command line flags used by the JVM. This is a useful flag to see the values selected by Java Ergonomics.

$ java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=259964992 -XX:MaxHeapSize=4159439872 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC 
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)


My laptop is detected as a server-class machine as I'm running Ubuntu 64-bit version. I have 16GB memory.

$ free 
             total       used       free     shared    buffers     cached
Mem:      16247812   13500596    2747216    1020860     172252    7987388
-/+ buffers/cache:    5340956   10906856
Swap:     18622460      42072   18580388


So, as explained in Java Ergonomics, we can see that the initial heap size is 1/64 of physical memory and maximum heap size is 1/4 of physical memory.

$ echo $(((16247812 * 1024) / 259964992))
64
$ echo $(((16247812 * 1024) / 4159439872))
4


You can also notice that the parallel garbage collector (-XX:+UseParallelGC) is selected by the JVM.

Printing Initial JVM Flags


$ java -XX:+PrintFlagsInitial -version


When printing the JVM flags, we can see there are several columns. Those columns are type, name, assignment operator, value and the flag type.

Use this command to see the default values.

Printing Final JVM Flags


See blog post on -XX:+PrintFlagsFinal to learn more details on each column.

$ java -XX:+PrintFlagsFinal -version


When printing final flags, we can see there are some flags with assignment operator ":=", which indicates that the flag values were modified (by manually or by Java Ergonomics)


$ java -XX:+PrintFlagsFinal -version | grep ':='



JVM Flag Types


All JVM Flags are categorized in to different types, which can be seen inside curly brackets in the -XX:+PrintFlagsInitial/-XX:+PrintFlagsFinal output.



$ java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UnlockCommercialFeatures -XX:+PrintFlagsFinal -version  |  awk -F ' {2,}' '{print $4}' | sort -u 
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)

{ARCH diagnostic}
{ARCH experimental}
{ARCH product}
{C1 diagnostic}
{C1 pd product}
{C1 product}
{C2 diagnostic}
{C2 experimental}
{C2 pd product}
{C2 product}
{commercial}
{diagnostic}
{experimental}
{lp64_product}
{manageable}
{pd product}
{product}
{product rw}


As mentioned in the blog post on -XX:+PrintFlagsFinal , we can find some details on these flag types from the JDK source file:
http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/tip/src/share/vm/runtime/globals.hpp

Following are the meanings of above flag types

  • product - General Flags for JVM, which are officially supported.
  • product rw - Writable internal product flags
  • manageable - Writable external product flags.
  • diagnostic - These flags are not meant for JVM tuning or for product modes. Can be used for JVM debugging. Need to use -XX:+UnlockDiagnosticVMOptions
  • experimental - These flags are in support of features, which are not part of officially supported product. Need to use -XX:+UnlockExperimentalVMOptions
  • commercial - These flags are related to commercial features of the JVM. Need a license to use in production. Need to use -XX:+UnlockCommercialFeatures
  • C1 - Client JIT Compiler specific flags
  • C2 - Server JIT Compiler specific flags
  • pd - Platform dependent flags
  • lp64 - Flags for 64bit JVM
  • ARCH - Architecture (CPU: x86, sparc etc) dependent flags

JVM Flag Data Types



$ java -XX:+PrintFlagsFinal -version | awk '{if (NR!=1) {print $1}}' | sort -u
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
bool
ccstr
ccstrlist
double
intx
uint64_t
uintx


The data types for JVM Flags are intuitive.

  • bool - Boolean (true/false)
  • ccstr - String
  • ccstrlist - Represents String arguments, which can accumulate
  • double - Double
  • intx - Integer
  • uint64_t - Unsigned long
  • uintx - Unsigned integer


Summary


If you ever wanted to find out all possible JVM flags, the -XX:+PrintFlagsFinal flag is the solution for you. Java Ergonomics select the best values depending on the environment and it's important to be aware of the Java Ergonomics when tuning your application.


Comments

Popular posts from this blog

Java Performance Monitoring Libraries

Specifying a custom Event Settings file for Java Flight Recorder

Java CPU Flame Graphs