Sunday, 9 October 2016

10 Essential JVM Options for a Java Production System

This is a brief guide of important JVM options which you will often see with production Java systems. As a Java developer, you should know what these JVM options means and their importance. You will find that most of the JVM options are related to heap memory settings, garbage collection and to log some details e.g. heap dump, necessary for troubleshooting any issue e.g. memory leak or excessive memory consumption. It's ok if you don't know them yet but you should know them and that's the objective of this article. How do you find the JVM options your application is using? Well, you can see the startup scripts through which your application is started. Alternatively, if your application is running on Linux you can do ps -ef | grep java to find the Java process and see the JVM options printed as process arguments. If more than one Java process is running on the system then you may need to search with a keyword which is unique to your Java application.

Remember, your process might not catch with ps -ef, if the argument list is too long, so you can also try using ps -auxww command, which shows the process with a long argument list as well. Once you have that list of JVM flags, you can understand certain behaviors of any Java application e.g. Tomcat, particularly how much memory is left to grow etc.

Btw, this is not the guide for JVM performance tuning, it will just let you familiar with essential JVM options from Java developer's perspective.

Must Know JVM options for Java Developers

Here is my list of essential JVM options which are must for any productions system and I strongly believe that every Java developer should be familiar with these Java virtual machine flags. The list is not big and it just include the most popular options. It doesn't include JVM options related to 32-bit or 64-bit or something like -XX:UseCompressedOOP, which is quite important for 64-bit Java virtual machine. For a more comprehensive list of JVM options, you can see this list.

1) -Xms
This option is to specify starting heap size for JVM e.g. -Xms2048m means initial heap size of JVM is 2GB. When JVM will start the heap memory will be this big. This is done to prevent resizing during startup and improve the startup time of JVM.

2) -Xmx
This option is to specify maximum heap size of JVM e.g. -Xmx2048m means maximum heap size of JVM will be 2GB. You will almost always see -Xms and -Xmx together. Their ration is also important, the ration of 1:1 or 1:1.5 is found to be more efficient. You must specify sufficient heap space for your Java application to avoid java.lang.OutOfMemoryError: Java Heap space, which comes if there is not enough memory to create new objects or arrays.

3) -XX:PermSize
Earlier JVM options specify the size of heap memory but this one is to specify the size of PermGen space, where string pool and class metadata is stored. This option is very important for the web server like Tomcat which often loads classes of the web application during deployment. It's worth knowing that PermGen space is replaced by MetaSpace in Java 8 and this option is not relevant if you are running with JRE 8 JVM.

4) -XX:MaxPermSize
This is the counterpart of earlier JVM option and used to specify the maximum size of permanent generation of JVM. The permgen will expand until it reaches this value, It cannot expand beyond this. If the permanent generation of JVM is full then you will get java.lang.OutOfMemoryError: PermGen space. So, this option is very important to avoid that error.

5) -verbose:gc
This JVM option is used to enable Garbage collection logging in your Java application. It will show you whether it's major or minor garbage collection, which kind of garbage collector is used, how much memory is reclaimed and how much time it took etc.

6) -XX:+PrintGCTimeStamps
This JVM option will prepend record with timestamp since Java application start, so you can see that at which state of your application GC activity peaks.

7) -XX:+PrintGCDetails 
Prints some more garabage collections details

8) -Xloggc:[path to gc log file]
You can log all garbage collection details into a log file for future analysis using this JVM option. You can later use tools like GCViewer to analyze the logs files.

10 Essential JVM Options for a Java Production System

This is an essential JVM option if your Java program connects to database or any other Java processor web server via a load balancer e.g. in which hostname can be routed to the different IP address in case of failover. This option specifies the number of seconds during which DNS record will be cached in JVM. This is even more important with Java 6 virtual machine which caches the IP address forever. In that case, you don't have other option but to restart your Java application if upstream or database switched to the secondary node, not the most elegant option.

10) -XX:+HeapDumpOnOutOfMemoryError
This JVM option creates a heap dump when your JVM dies with OutOfMemory Error. There is no overhead involved unless an OOM actually occurs. This flag is a must for production systems as it is often the only way to further analyze the problem. The heap dump will be generated in the "current directory" of the JVM by default. If you want to create heap dumps on specific directory then use -XX:HeapDumpPath=[path-to-heap-dump-directory] e.g. -XX:HeapDumpPath=/dsk3/dumps.

Remember that the heap dump file can be huge, up to Gigabytes, so ensure that the target file system has enough space. 

That's all in the least of essential JVM options must for a Java production system. As I said, every Java developer should familiar with these options and should not put the Java application into production without having these JVM options. You may need to put more JVM option e.g. to select a garbage collector e.g. ConcurrentMarkSweep or G1 and other network related parameters but this is a bare minimum set of JVM option for any production Java system.

Related Posts