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.
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.
You can also notice that the parallel garbage collector (-XX:+UseParallelGC) is selected by the JVM.
$ 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