Cross Column

Showing posts with label PrintFlagsFinal. Show all posts
Showing posts with label PrintFlagsFinal. Show all posts

Saturday, November 8, 2014

HotSpot: GC Worker Threads Used in CMS, Parallel, and G1 GC

As discussed in [1], the Java HotSpot virtual machine includes five garbage collectors (or GC):
  • Serial Collector
  • Parallel Collector (or throughput collector)
  • Parallel Compacting Collector
  • Concurrent Mark-Sweep (CMS) Collector
  • Generation First (G1) Garbage Collector
Also, in [2], we have shown how to find the default HotSpot JVM values.  Some VM options are set from command line and some are set by GC's ergonomics.  However, all VM options are printed when you execute:
  • -XX:+PrintFlagsFinal
Using G1 GC as an example, it uses SurvivorRatio, but not InitialSurvivorRatio, MinSurvivorRatio, or TargetSurvivorRatio.  In this article, we will show you one way to tell which VM option is used by which GC.

GC Threads


In [3], we have discussed the difference between Parallel Collectors and Concurrent Collectors.

Parallel collectors require stop-the-world pause for the whole duration of major collection phases (mark or sweep), but employ all available cores to compress pause time. Parallel collectors usually have better throughput, but they are not a good fit for pause critical applications. 
Concurrent collectors try to do most work concurrently (though they also do it in parallel on multi-core systems), stopping the application only for short duration. Note that the concurrent collection algorithm in JRockit is fairly different from both HotSpot's concurrent collectors (CMS and G1).

There are three kinds of GC threads utilized in HotSpot for CMS, Parallel, and G1 garbage collectors:
  • ParallelGCThreads
  • ConcGCThreads 
  • G1ConcRefinementThreads
When you use PrintFlagsFinal to print out all JVM flags for CMS, Parallel or G1 GC.  The results are as follows:

CMS
    uintx ParallelGCThreads           = 23     {product}
    uintx ConcGCThreads               = 6      {product}
    uintx G1ConcRefinementThreads     = 0      {product}
Parallel GC     uintx ParallelGCThreads           = 23     {product}     uintx ConcGCThreads               = 0      {product}     uintx G1ConcRefinementThreads     = 0      {product}
G1 GC
    uintx ParallelGCThreads           = 23     {product}
    uintx ConcGCThreads               = 6      {product}
    uintx G1ConcRefinementThreads     = 23     {product}

Based on JDK-8047976,[4] it says that GC's normally don't update flags they do not use.  That's why we see "0" in some of the printouts.  To summarize, here are the GC worker threads used in CMS, Parallel, and G1 garbage collectors:

Garbage Collector
Worker Threads Used
CMS
ParallelGCThreads
ConcGCThreads
Parallel
ParallelGCThreads
G1
ParallelGCThreads
ConcGCThreads
G1ConcRefinementThreads

Note that the above description is valid for the following JVM version or later ones:
java version "1.8.0_40-ea"
Java(TM) SE Runtime Environment (build 1.8.0_40-ea-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b16, mixed mode)
Because JDK-8047976 bug,[4] the behavior is different if you use earlier versions.

References

  1. HotSpot VM Performance Tuning Tips (Xml and More)
  2. What Are the Default HotSpot JVM Values? (Xml and More)
  3. JRockit: Parallel vs Concurrent Collectors (Xml and More)
  4. Ergonomics for GC thread counts should update the flags
  5. Tuning that was great in old JRockit versions might not be so good anymore
    • Trying to bring over each and every tuning option from a JR configuration to an HS one is probably a bad idea.
    • Even when moving between major versions of the same JVM, we usually recommend going back to the default (just pick a collector and heap size) and then redoing any tuning work from scratch (if even necessary).
  6. HotSpot VM options (JDK 8)

Friday, August 1, 2014

HotSpot: What Does {pd product} Mean?

In [1], we have discussed how to find out default HotSpot JVM values.  In the output, you may have spotted:
{pd product}
What does it mean? In this article, we will examine that in depth.

Platform Dependent


{pd product} means platform-dependent product option.  First of all, if a flag is a product option, maybe you want to pay attention to it and may want to change its value for better performance.  If it's an experimental or diagnostic flag, you may want to ignore it.

If an option is {pd product}, it means that its default value will be dependent on which platform its implementation would be compiled on.  Currently, these platforms are supported, but not limited to:
  • ARM
  • PPC
  • Solaris
  • x86

Examples


Two of the {pd product} flags, we would like to discuss here further.  In JDK 7u51,[2] they have the following default values on x86 platforms:

    uintx ReservedCodeCacheSize     = 50331648        {pd product}
    bool  TieredCompilation         = false           {pd product}

These default values have been changed in later JDK 8 builds.  For example, in JDK 8u20, they have the following default values on the same server:

    uintx ReservedCodeCacheSize     = 251658240        {pd product}
    bool  TieredCompilation         = true             {pd product}

As discussed in [3,4], you may want to tune these flags for better performance.


References

  1. What Are the Default HotSpot JVM Values?
  2. Java™ SE Development Kit 7, Update 51 (JDK 7u51)
  3. Performance Tuning with Hotspot VM Option: -XX:+TieredCompilation (XML and More)
  4. A Case Study of Using Tiered Compilation in HotSpot (XML and More)  

Tuesday, June 5, 2012

What Are the Default HotSpot JVM Values?

Updated (09/16/2014):

In the latest JDK 8 releases, it only prints out product level options if you use, say, -XX:+PrintFlagsFinal.  To print other options, you could do something like this:
../bin/java -XX:+PrintFlagsFinal -XX:+UnlockExperimentalVMOptions  
  -XX:+UnlockDiagnosticVMOptions -version

Oftentimes you will find the needs to understand better the options provided by Oracle's (formerly Sun's) HotSpot Java Virtual Machine.  For example, when you try to tune the performance of Java applications, you definitively want to know what JVM parameter values are chosen by default.  From the defaults, you might start fine-tuning their values based on your application's characteristics.

There are two JVM options which can be useful to you:
  • -XX:+PrintFlagsInitial 
  • -XX:+PrintFlagsFinal
At JVM startup, the system will print the initial/final JVM values used.  The values provided by PrintFlagsInitial are values set by default and the values printed for PrintFlagsFinal are final values chosen after the dynamic runtime changes are made based on your hardware environment.

-XX:+PrintFlagsFinal


For example, if  PrintFlagsFinal is specified, at the beginning of the WebLogic server log file, you can find:

starting weblogic with Java version:
java version "1.7.0_04-ea"
Java(TM) SE Runtime Environment (build 1.7.0_04-ea-b17)
Java HotSpot(TM) 64-Bit Server VM (build 23.0-b18, mixed mode)
Starting WLS with line:
/export/home/bench/workload/target_jvm/jdk-hs/bin/java -server -Xms6400m -Xmx6400m -XX:+AggressiveOpts ...


[Global flags]

    uintx AdaptivePermSizeWeight                    = 20              {product}          
    uintx AdaptiveSizeDecrementScaleFactor          = 4               {product}          
    uintx AdaptiveSizeMajorGCDecayTimeScale         = 10              {product}          
    uintx AdaptiveSizePausePolicy                   = 0               {product}          

...
    uintx MinHeapFreeRatio                          = 0               {manageable}
    uintx MaxHeapFreeRatio                          = 100             {manageable}
     intx WorkAroundNPTLTimedWaitHang               = 1               {product}          
    uintx WorkStealingHardSpins                     = 4096            {experimental}     
     intx WorkStealingSleepMillis                   = 1               {experimental}     
    uintx WorkStealingSpinToYieldRatio              = 10              {experimental}     
    uintx WorkStealingYieldsBeforeSleep             = 5000            {experimental}     
    uintx YoungGenerationSizeIncrement              = 20              {product}          
    uintx YoungGenerationSizeSupplement             = 80              {product}          
    uintx YoungGenerationSizeSupplementDecay        = 8               {product}          
    uintx YoungPLABSize                             = 1024            {product}          
     bool ZeroTLAB                                  = false           {product}          
     intx hashCode                                  = 0               {product}           

In case you wonder what "x" means in the types intx and uintx, intx and uintx are the 'extended' int and 'extended' unsigned int types—They are 32bit wide on a 32-bit platform and 64bit wide on a 64bit platform.

Parameter Scope


The last value from the output specifies the scope of parameter, or when it can be used.  For example, if the value is
  • {experimental}
It means that you need to specify
  • -XX:+UnlockExperimentalVMOptions
to set the parameter.

Similarly, you can provide
  • -XX:+UnlockDiagnosticVMOptions
to enable the tuning of a parameter if the its scope is:
  • {C1 diagnostic} or
  • {C2 diagnostic}
C1 and C2 here relate to the JIT compiler used.  C1 is for the client VM while C2 is for the server's.

Finally,  if flags are marked as manageable, they are dynamically writeable through the JDK management interface (com.sun.management.HotSpotDiagnosticMXBean API) and also through JConsole. The manageable flags can also be set through jinfo -flag.

Test


We know the scope of  UseCriticalJavaThreadPriority parameter is experimental.  If we set it without specifying -XX:+UnlockExperimentalVMOptions first, here is the result:

$ /export/home/bench/workload/target_jvm/jdk-hs/bin/java -server -XX:+PrintFlagsFinal  
  -XX:+UseCriticalJavaThreadPriority -version >tmp.tmp
Unrecognized VM option 'UseCriticalJavaThreadPriority'
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

However, if you add  -XX:+UnlockExperimentalVMOptions, you will be allowed to set its value :

$ /export/home/bench/workload/target_jvm/jdk-hs/bin/java -server -XX:+PrintFlagsFinal 
  -XX:+UnlockExperimentalVMOptions -XX:+UseCriticalJavaThreadPriority -version >tmp.tmp
java version "1.7.0_04-ea"
Java(TM) SE Runtime Environment (build 1.7.0_04-ea-b17)
Java HotSpot(TM) 64-Bit Server VM (build 23.0-b18, mixed mode)

Finally, remember to add -version at the end as shown here:

$jdk-hs/bin/java -server -XX:+PrintFlagsFinal -XX:+UseSerialGC -version >tmp5.txt

For example, if you specified options in this order, it would ignore -XX:+UseSerialGC setting:

$jdk-hs/bin/java -server -XX:+PrintFlagsFinal -version -XX:+UseSerialGC >tmp6.txt

 

How about JRockit?


For JRockit, you use:
  •  ./java -Xprintflags -version

 

Notes

  • {pd product} means platform dependent

 

References

  1. HotSpot JVM Options Displayed: -XX:+PrintFlagsInitial and -XX:+PrintFlagsFinal
  2. Inspecting HotSpot JVM Options
  3. Redux: Inspecting HotSpot JVM Options
  4. Oracle® JRockit Command-Line Reference Release R28
  5. Default Values of JRockit's VM Options (XML and More)
  6. HotSpot Glossary of Terms