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. You should refer Java Performance The Definitive Guide By Scott Oaks for a comprehensive learning on JVM internals and Java performance tuning.

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. See Java Performance Companion by Charlie Hunt to learn more about Java 8 changes and their performance impact. It is the most up-to-date book in Java performance till date and help you to squeeze the best performance with JDK 8 in any application.

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.

Essential JVM options for Java production application

9) -Dsun.net.inetaddr.ttl=
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. You can also refer Java Performance Companion 1st edition by Charlie Hunt to learn more about analyzing heap dump and thread dump in Java.

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 Java and JVM tutorials for Java programmers
  • What is the difference between JRE, JDK, and JVM in Java? (answer)
  • How do you find if JVM is 32-bit or 64-bit? (answer)
  • What is maximum heap size of 32-bit and 64-bit JVM in Windows and Linux? (article)
  • What is the difference between Oracle HotSpot JVM and IBM  JVM? (answer)
  • When is a class loaded and initialized in JVM? (answer)
  • What is the difference between Stack and Heap Memory in JVM? (answer)
  • 5 Books to Learn Java Performance Tuning (list)

Further Learning
Java Memory Management
Understanding the Java Virtual Machine: Class Loading and Reflection
Java Performance The Definitive Guide


  1. Nice article, but actually sun.net.inetaddr.ttl is NOT a system property, it's a security property. You cannot change the value with a -D option afaik.

  2. There're also some options out there that allow you to specify the GC strategy, depending on the performance requirements.