Oct 02

Looking Inside a JVM: -XX:+PrintFlagsFinal

Java’s twenty years old now — next year Duke can have Irish Coffee! Seriously, though, in that time there’s been a lot of changes to the Java Virtual Machine (JVM). What once was true may no longer be the case. In digging into an issue I discovered a nice feature of the JVM which enables being able to definitively state the effects of a particular switch as well as decisions made by JVM heuristics on a JVM/Host pair — just because something might be true on a particular host doesn’t mean it’s true everywhere!

There is a helpful switch added post 1.6.0_14 (I believe it was added at 1.6.0_18, but am not certain): -XX:+PrintFlagsFinal which outputs the values of all of the jvm configuration parameters and/or values. A snippet of the output may be seen below:

This is very helpful in terms of determining the effect (or lack thereof) of an argument on the JVM. Additionally, you can determine the values computed by the heuristics on a particular host/JVM combination. It can be invoked as follows:

That invocation lets you “watschen der blinkinlights” and also save the results to a file. If you were interested in seeing how a particular set of arguments impacted the startup time of the JVM, you could prepend the command with time. However, should you do so, run it more than once and take the average.

Here are some of the things you can discover (there are hundreds):

Parameter Description
InitialHeapSize The minimum size of the heap in KB.
MaxHeapSize The maximum size of the heap in KB. On most machines today this will be equivalent to 1/4 the ram.
NewSize Size of the Young Generation (or Eden Space)
OldSize Size of the Old Generation
ParallelGCThreads Number of threads used for garbage collection. Up to 8 cores this corresponds to the number of cores available
SelfDestructTimer The number of minutes before the JVM will terminate. (0 means it won’t). I just discovered it; this could be fun on April Fools Day.
This will show the type of garbage collection being used. Typically (as of 2015) it will be the Parallel Garbage Collector


The following examples are on a quad core linux host with 12GB of RAM using JDK 1.8.0_60.


From a couple of tests I’ve performed, the stock InitialHeapSize is 1/16 the size of the MaxHeapSize. However, “you don’t have to take my word for it“.

Setting a Maximum Heap Size or Minimum, But Not Both

Here the MaxHeapSize is set to 1G. Note that the InitialHeapSize has remained constant:

Setting the InitialHeapSize but not the MaxHeapSize — the max goes back to the default:

Changing the Garbage Collector

JDK 1.8 provides several collectors. At present (1.8.0_60), the default garbage collector on this machine is the Parallel garbage collector. It is believed that this will change to the G1 garbage collector in 1.9.

flickr photo shared by JD Hancock under a Creative Commons ( BY ) license

One of these things is not like the others. Notice that the Serial garbage collector is single threaded.

Also take note which collectors have (or do not have) UseParallelOldGC or UseParNewGC set to true; it’s pretty interesting.

Not All JVM are Created Equal

To illustrate, here are the defaults from another Linux host; this one has 8 cores and 32G of ram:

View post on imgur.com

Here are the defaults from a JVM on a Raspberry Pi B+ (1 Core, 512M of ram):

It’s just a little different….

This started as a blog post to help me remember a nifty switch I’d discovered today; it’s grown a little bit and I’ve learned some new things along the way!

One last thought, however. Don’t assume that you know how the JVM is going to behave in a particular version on a particular host.

1 ping

  1. Docker, Cgroups, Memory Constraints, and Java: A Cautionary Tale, or Here be Reapers (sometimes) » Ramblings

    […] year I wrote in Looking Inside a JVM: -XX:+PrintFlagsFinal about finding the values configured in the JVM at runtime. By not specifying a heap size, I get the […]

Leave a Reply

%d bloggers like this: