Cross Column

Showing posts with label Hotspot VM Option. Show all posts
Showing posts with label Hotspot VM Option. Show all posts

Friday, September 14, 2012

HotSpot Performance Option — SurvivorRatio

As shown in [1], -XX:SurvivorRatio has been classified as a performance option on HotSpot VM.

In this article, we will discuss how this option works and how it can impact an application's performance.

Survivor Spaces


The young generation space in all HotSpot garbage collectors is subdivided into an eden space and two survivor spaces.  Eden space is where new Java objects are allocated.  One of the survivor spaces is labeled the “from” survivor space, and the other survivor space is labeled the “to” survivor space.

If during a minor garbage collection, the “to” survivor space is not large enough to hold all of the live objects being copied from the eden space and the “from” survivor space, the overflow will be promoted to the old generation space. Overflowing into the old generation space may cause the old generation space to grow more quickly than desired and result in an eventual stop-the-world compacting full garbage collection.

If you are interested to learn more on garbage collector, read this excellent book— "Java Performance."


-XX:SurvivorRatio


For the following discussions, we will use the following HotSpot command options:
  • -server -Xms2560m -Xmx2560m -Xmn512m -XX:SurvivorRatio=4
In other words, we have set Young Generation size to be 512MB and the Survivor Ratio to be 4.  Since we didn't specify which Garbage Collector to be used, the default GC (i.e., -XX+UseParallelGC ) is selected.

When you set the SurvivorRatio to be 4, it means that:
  • The ratio of eden/survivor space size will be 4. The default value is 8.
Below we will see how the setting of SurvivorRatio will impact the sizes of  survivor spaces.

If InitialSurvivorRatio or MinSurvivorRatio were not specified, but the SurvivorRatio has been set, their values will be set to:
  • SurvivorRatio + 2
Then the calculation is as follows (Note that young_gen_size is the value specified with -Xmn):

  size_t survivor_size = young_gen_size / InitialSurvivorRatio;
  eden_size = size - (2 * survivor_size);


So, for SurvivorRatio = 4, different spaces are derived as follows:

 InitialSurvivorRatio = SurvivorRatio + 2 = 6
 survivor_size = 512m / 6 = 87360K  (Note that young_gen_size = 512m)
 eden = young_gen_size - 2 * survivor_size = 512m - 2 *  87360K  = 349568K
 young_gen_total(as reported in the gc print below) = eden + 1*survivor = 436928K

How to Verify?


When we started the application, we have specified the following GC-related print options:
  • -Xloggc:/<your_path>/logs/gc_0.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintReferenceGC 

After the application (i.e., a benchmark in our case) ends, you can find the following printouts at the end of gc_0.log:

Heap
PSYoungGen total 436928K, used 64296K [0x00000007e0000000, 0x0000000800000000, 0x0000000800000000) 
  eden space 349568K, 15% used [0x00000007e0000000,0x00000007e3571608,0x00000007f5560000)
  from space 87360K, 10% used [0x00000007f5560000,0x00000007f5eb8cd0,0x00000007faab0000)
  to space 87360K, 0% used [0x00000007faab0000,0x00000007faab0000,0x0000000800000000)
ParOldGen total 2097152K, used 1457708K 
[0x0000000760000000, 0x00000007e0000000, 0x00000007e0000000) 
  object space 2097152K, 69% used [0x0000000760000000,0x00000007b8f8b2a8,0x00000007e0000000)
PSPermGen total 393216K, used 246405K 
[0x0000000748000000, 0x0000000760000000, 0x0000000760000000) 
  object space 393216K, 62% used [0x0000000748000000,0x00000007570a14c0,0x0000000760000000)

As you can see it:
  • eden space / from space = 349568K / 87360K = 4
  • PSYoungGen total =  349568K +  87360K = 436928K

Why It's a Performance Option?


Given there is limited physical memory, you can increase heap to a certain limited size.  After that, you can tune survivor ratio to see if short lived objects can be allowed a longer time period to die in the young generation  (or if they can be promoted less directly into the old generation), which could help overall response time.

Bottom line: larger survivor spaces allow short lived objects a longer time period to die in the young generation and this helps application's response time (in other words, there will be less long-paused full garbage collections).

Acknowledgement


Some of the writings here are based on the feedback from Jon Masamitsu and Scott Oaks. However, the author would assume the full responsibility for the content himself.

References

  1. Java HotSpot VM Options
  2. The Fault with Defaults
  3. Garbage Collector Ergonomics
  4. Java Performance by Charlie Hunt and Binu John

Wednesday, April 11, 2012

Performance Tuning with Hotspot VM Option: -XX:+TieredCompilation

Updated (09/26/2014):

In the latest JDK 8 release,[20] TieredCompilation is ON by default. Depending on platforms, default ReservedCodeCacheSize is bigger too.  For example, on Linux 64-bit platforms, its default size is 240MB.

Hotspot has two JITs named c1 (i.e., client JIT) and c2 (i.e., server JIT)[1,5,6]. The client JIT starts fast but provides less optimizations. So, it is used for GUI application. The server JIT starts more slowly but provide very good optimizations. The idea of tiered compilation is to get the best of both compilers, first JITs the code with c1 and then if the code is really hot to recompile it with c2.

The tiered server runtime is enabled with the following Hotspot VM options:
  • -server -XX:+TieredCompilation
In this article, we will show you how to tune code cache size (i.e., -XX:ReservedCodeCacheSize[4]) if tiered compilation is enabled. With the latest Hotspot builds,[19] we did see some performance improvement if tiered compilation is enabled. However, we also noticed that if your code cache size is not big enough, it may negatively impact your application's performance (i.e., Response Time).

PrintCompilation


Before any performance tuning, you would like to learn how JIT compiler behaves first. You can track the behavior of the JIT compiler with:
  • -XX:+PrintCompilation [4]
With this VM option, JVM will print message when a method is compiled as follows:

 66    4     n 0     java.lang.System::arraycopy (0 bytes)   (static)
 66    5       3     java.lang.String::hashCode (67 bytes)
 67    1       3     java.lang.String::equals (88 bytes)
 68    2       3     java.lang.String::charAt (33 bytes)
504   69   !         java.util.jar.Attributes::read (410 bytes)
522   70             java.util.jar.Attributes$Name::isValid (45 bytes)
522   69   !         java.util.jar.Attributes::read (410 bytes)   made not entrant
864   69   !         java.util.jar.Attributes::read (410 bytes)   made zombie

Without much ado, we will refer you to read [5] for detailed explanation of each field in the output. For our purpose, we are interested in finding out:
  • How many methods have been compiled at the beginning of, say, 10 minutes?
You can find out that by counting the lines in the log file:
  • grep :: <logfile> | wc -l
since the compilation lines all have "::" in them. Based on this information, you can estimate what size of code cache size should be for better performance. You can also use this command line option along with instrumenting the benchmark to indicate when it has completed the warm-up period. For example, if you are observing -XX:+PrintCompilation output during the measurement interval, then benchmark has not reached JIT compiler steady state.

ReservedCodeCacheSize


To improve application's performance, you can set the maximum code cache size:
  • -XX:ReservedCodeCacheSize=256m
when tiered compilation is enabled for your JVM. ReservedCodeCacheSize (and InitialCodeCacheSize) is an option for the (just-in-time) compiler of the Java Hotspot VM. Basically it sets the maximum size for the compiler's code cache. In 1.5.0_06 and earlier, the default was 1024MB for Solaris 64-bit and amd64. Now the default is 48MB for Solaris 64-bit, amd64, and -server x86.

In our experiments, we have measured the performance of ATG CRM Demo application with different maximum code cache sizes. Here are our findings:


-TC
64M
+TC
64M
+TC
128M
+TC
256M
+TC
512M
+TC
1024M
Response Time
(seconds)
0.236 Failed 0.496 0.227 0.226 0.223

TC: Tiered Compilation
nnnM: Reserved Code Cache Size

Conclusion


As the benchmark results show, you can tune your application's performance by enabling tiered compilation with appropriate setting of code cache size. To estimate how much code cache to reserve, you can connect to the JVM using jconsole and use the memory tab to see how much code cache is filled.  The performance improvement may vary based on your JVM versions and system capabilities.  But, before you do any fine tuning, read [9] first.

Finally, be warned that options that are specified with -XX are not stable and are not recommended for casual use. These options are subject to change without notice[4].

References

  1. Tiered Compilation 
  2. PrintCompilation JVM flag
  3. Infrastructure for Tiered Compilation Support
  4. Java Hotspot VM Options
  5. About PrintCompilation
  6. JVM Runtime Compilers: -client or -server 
  7. Java Tuning White Paper
  8. A Case Study of Using Tiered Compilation in HotSpot 
  9. HotSpot VM Performance Tuning Tips (XML and More)
  10. Java Performance by Charlie Hunt, Binu John, David Dagastine
  11. All other performance tuning articles on XML and More
  12. Using JConsole
  13. How to Troubleshoot High CPU Usage of Java Applications? (XML and More)
  14. HotSpot: Using jstat to Explore the Performance Data Memory (XML and More)
  15. Understanding String Table Size in HotSpot (XML and More)
  16. HotSpot VM Performance Tuning Tips (XML and More)
  17. HotSpot Performance Option — SurvivorRatio (XML and More)
  18. All other performance tuning articles on XML and More
  19. JDK 7u40 (Java(TM) SE Runtime Environment: build 1.7.0_40-b43)
    • Default values for linux-x64:
  20. JDK 8: Revisiting ReservedCodeCacheSize and CompileThreshold (Xml and More)
  21. HotSpot Virtual Machine Garbage Collection Tuning Guide
  22. Garbage-First Garbage Collector Tuning

© Travel for Life Guide. All Rights Reserved.

Analytical Insights on Health, Culture, and Security.