10 Essential JVM Options for a Java Production System

Hello guys, this is a brief guide of relevant JVM options which you will often see in production Java systems. As a Java developer, you should know what these JVM options means, their importance, and how they affect your application. You will find that most of the JVM options are related to heap memory, garbage collection and to log some details, e.g., heap dump, necessary for troubleshooting heap related issues like a memory leak or excessive memory consumption. It's Ok if you don't know these Java virtual machine options yet, but you should be familiar with them, and that's the objective of this article. Btw, 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.  I know these are Linux commands but didn't I said that Linux is a good tool in the arsenal of any developer.

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. But, if you want to learn JVM tuning in-depth, you should refer to Understanding the Java Virtual Machine courses on Pluralsight. This is a series of courses on JVM which provides comprehensive learning on JVM internals and Java performance tuning, including security and classloading.

Top 10 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 includes 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.

1) -Xms

This option is to specify starting heap size for JVM, e.g., Xms2048m means an initial heap size of JVM is 2GB. When JVM starts 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 the maximum heap size of JVM, e.g., Xmx2048m means a 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 a web server like Tomcat, which often loads classes of the web application during deployment.

Btw, 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.

If you are interested in further learning, you can also check the Java Memory Management course on Udemy to learn more about JVM memory architecture and how to tune them properly.

Useful JVM memory options

4) -XX:MaxPermSize

This is the counterpart of the earlier JVM option and used to specify the maximum size of the 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 but only if you are running in Java 7 or lesser version. After Java 7, this option is deprecated.

5) -verbose:gc

This JVM option is used to enable Garbage collection logging in your Java application, which is very important for the latency-sensitive application. I used to work on systems where we strive for microsecond latencies, and if you remember, a major garbage collection can last several milliseconds.

So, we strive for GC free architecture like LMAX Disrupter, but even if you are not working for ultra latency-sensitive application, this handy option will tell you important GC statistics.

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.

If you want, you further join Understanding the Java Virtual Machine: Memory Management course on Pluarlsight to learn more about memory management, Garbage collection, and JVM tuning from experts.
Useful JVM garbage collection options.

6) -XX:+PrintGCTimeStamps

This JVM option will prepend record with timestamp since Java application starts 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.

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.

It is the most up-to-date book in Java performance to date and helps you to squeeze the best performance with JDK 8 in any application.

That's all in the least of essential JVM options must for a Java production system. As I said, every Java developer should be 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.

Btw, this list is no more a comprehensive list and only covers most common and essential JVM options, For a more comprehensive list of JVM options, you can check following resources.

Further Learning
Java Memory Management
Understanding and Solving Java Memory Problems 

Related Java and JVM tutorials for Java programmers
  • 10 Things Java Developer Should learn in 2019 (goals)
  • 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)
  • 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)
  • 10 Free Java Courses for Programmers (courses)
  • 10 Tips to become a better Java developer (tips)
  • What is the maximum heap size of 32-bit and 64-bit JVM on Windows and Linux? (article)
  • What is the difference between Oracle HotSpot JVM and IBM  JVM? (answer)

Thanks for reading this article so far. If you like this article, then please share it with your friends and colleagues. If you have any questions or feedback, then please drop a note.


  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.