Java Performance Tuning


If you have ever thought about Java technology for you application landscapen, you might have been in touch with the usual Java performance topic. One big part on this topic is the configuration of the Java Garbage Collector (GC). There are several articels about this topic; my favorite one is from cubrid.org, which separated the topic into multiple parts:

  1. Become a Java GC Expert
  2. Understanding Java Garbage Collection
  3. How to Tune Java Garbage Collection

Other websites, such as javapapers.com, also published good articles about the technology.

Java Garbage Collection Process

Java has a given process for handling data objects. Any new object will automatically move to the eden space. If the eden space is full a non-blocking minor garbage collection is triggered. Within a minor garbage collection any object of the young generation will be removed, if no references to the object exists. To do so, its inherited finalize method is called by the Java garbage collector. All other objects will be moved to the survivor space. As there are two spaces, the one which is currently empty, will be used. All objects from the other survivor space are also moved to the same survivor space, if references to its objects exists. Objects without references will also be removed and therefore the previous survivor space cleaned up. Therefore only one survivor space will always be in use.

After a configurable amount of jumps between both survivor spaces, objects are being promoted for the tenured generation. The tenured generation consists of long-living objects only. If this generation is full, a blocking major garbage collection is executed. During a major garbage collection (which is also called full garbage collection) the application pauses (interruptes) its execution until the garbage collection is completed. There are different type of garbage collections to optimize this blocking event which will be explained below.

Types of Garbage Collectors

Java has four types of garbage collectors for major garbage collections, which run differently and will influence your applications performance in different ways:

Serial
Garbage Collector
Parallel
Garbage Collector
CMS
Garbage Collector
Garbage First (G1)
Garbage Collector
Serial garbage collector works by holding all the application threads. It is designed for the single-threaded environments. It uses just a single thread for garbage collection. The way it works by freezing all the application threads while doing garbage collection may not be suitable for a server environment. It is best suited for simple command-line programs. Turn on the -XX:+UseSerialGC JVM argument to use the serial garbage collector.Parallel garbage collector is also called as throughput collector. It is the default garbage collector of the JVM. Unlike serial garbage collector, this uses multiple threads for garbage collection. Similar to serial garbage collector this also freezes all the application threads while performing garbage collection.Concurrent Mark Sweep (CMS) garbage collector uses multiple threads to scan the heap memory to mark instances for eviction and then sweep the marked instances. CMS garbage collector holds all the application threads in the following two scenarios only, while marking the referenced objects in the tenured generation space. if there is a change in heap memory in parallel while doing the garbage collection. In comparison with parallel garbage collector, CMS collector uses more CPU to ensure better application throughput. If we can allocate more CPU for better performance then CMS garbage collector is the preferred choice over the parallel collector. Turn on the XX:+USeParNewGC JVM argument to use the CMS garbage collector.G1 garbage collector is used for large heap memory areas. It separates the heap memory into regions and does collection within them in parallel. G1 also does compacts the free heap space on the go just after reclaiming the memory. But CMS garbage collector compacts the memory on stop the world (STW) situations. G1 collector prioritizes the region based on most garbage first. Turn on the –XX:+UseG1GC JVM argument to use the G1 garbage collector.   Java 8 Improvement Turn on the -XX:+UseStringDeduplication JVM argument while using G1 garbage collector. This optimizes the heap memory by removing duplicate String values to a single char[] array. This option is introduced in Java 8 u 20.
Scenario: Small amount of memory and CPU cores Client systemsScenario: ThroughputScenario: Response Time is crucialScenario: High performance
Disadvantage: Long blockingDisadvantage: Medium blocking CPU and Memory consumptionDisadvantage: CPU and Memory consumption Compaction step not provided by defaultDisadvantage: Not considered as \”stable\”, as it could even crash the JVM (2012)
-XX:+UseSerialGC-XX:+UseParallelGC-XX:ParallelGCThreads=-XX:+ParallelOldGC-XX:+UseConcMarkSweepGC-XX:+UseParNewGC-XX:+CMSPParallelRemarkEnabled-XX:CMSInitiatingOccupancyFraction=-XX:+UseCMSInitiatingOccupancyOnly-XX:ParallelCMSThreads=-XX:+UseG1GC-XX:+UnlockExperimentalVMOptions-XX:+UseStringDeduplication

Optimization Options

The mentioned Types of Garbage Collectors performance are based on the amount of memory used for the Java Virtual Machine (JVM). Therefore the adjustment of the memory limits can be considered as fine-tuning of the garbage collection behavior.

ClassificationOptionDescription
Heap Area-XmsInitial heap memory size
-XmxMaxmimal heap memory size
New Area-Xmn
-XX:NewSize
Size of Young Generation
-XX:PermSizeInitial Permanent Generation size
-XX:MaxPermSizeMaximum Permanent Generation size
GC Ratios-XX:NewRatioRatio between Young Generation and tenoured Generation
-XX:Survivor RationRatio between Eden space and Survivor spaces


These options can be provided as parameter, if you start Java applications manually (e.g. clients): 

java -Xmx12m -Xms3m -Xmn1m -XX:PermSize=20m -XX:MaxPermSize=20m -XX:+UseSerialGC -jar myApplication.jar

For middleware software, such as IBM WebSphere or Oracle WebLogic Server, you can also configure these options within the nodes configuration. For WebSphere you can find the configuration option within Application Servers / <Application Name> / Process Definition Java Virtual Machine: