Introduction
A method for inspecting the comprehensive set of HotSpot JVM options and some examples comparing different outputs.
Background
The Oracle JVM provides an enormous spectrum of options to control the runtime JVM. These options are given a criminally short and non-comprehensive discussion at the OTN here. OTN divides these options into three categories: Behavioural, Performance and Debugging. This is a useful abstraction but some examples Oracle gives in each category can be misleading due to the overlap between Behavioural and Performance.
The JVM options themselves can be controlled in a number of ways:
-XX:+PrintFlagsFinal
Usage
Let's see this in action! First let's run the following:
$ jdk1.6.0_23/bin/java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
(I have added -XX:+UnlockDiagnosticVMOptions as this unlocks more options for viewing and control. Also I have added -version at the end so Java doesn't complain that it has nothing to run and to supplement the results).
The sysout is quite large so I've saved it here. Firstly you may be surprised at the sheer quantity of JVM options available: 717! That's a lot of configuration! Before we dive into the options lets look at our host specification and the output of the -version option. The host has 8 dual core 64bit AMD Opteron processors running at 3.2GHz so 16 cores in total with 64GB of RAM. The Java -version output shows:
java version "1.6.0_23"
Java(TM) SE Runtime Environment (build 1.6.0_23-b05)
Java HotSpot(TM) Server VM (build 19.0-b09, mixed mode)
this tells us we are running Java 6 update 23 using the Server version of the HotSpot VM in 32bit mode. Now let's look closer at the output. For each option we can see the following columns:
Let's look closer at the modified options which have the := assignment:
uintx InitialHeapSize := 67108864 {product}
uintx MaxHeapSize := 1073741824 {product}
uintx ParallelGCThreads := 13 {product}
bool PrintFlagsFinal := true {product}
bool UnlockDiagnosticVMOptions := true {diagnostic}
bool UseParallelGC := true {product}
apart from the two flags which I set myself on the command line we can see Java ergonomics has given the heap a sensible range of 64MB to 1GB. The fairly old Parallel Garbage Collector has been chosen with an enormous 13 threads spawned to do the collection. Straightaway we've got a lot more insight into how our JVM is configured and a few ideas for improvements.
Client vs Server JVM Analysis
We know from looking at the -version output Java automatically chose the server JVM instead of the client JVM (Java automatically chooses server if it detects 64bit processors). But how do we know what options are set because Java chose the Server JVM? What options were set because of our host specification? Lets run the following commands and review the output:
$ jdk1.6.0_23/bin/java -client -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
$ jdk1.6.0_23/bin/java -server -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
I have saved the client output here and the diff client server here. Firstly lets look at the output from the Client JVM; it has 661 options, 56 fewer than the Server version. Now let's look solely at the Client options which have been modified, excluding the two options I set on the command line there are only two values which were changed:
uintx InitialHeapSize := 16777216 {product}
uintx MaxHeapSize := 268435456 {product}
so Java has chosen some fairly sensible values for the Client JVM: 16MB initial heap size with a max size of 256MB. There are many entries in the diff file mostly by virtue of the extra options available to the Server JVM or options which relate to memory simply having higher values. Here are the more interesting differences:
< intx CICompilerCount = 1 {product}
> intx CICompilerCount = 2 {product}
< intx CompileThreshold = 1500 {pd product}
> intx CompileThreshold = 10000 {pd product}
The Client VM waits only 1,500 invocations before compiling a method to native code and uses only one thread for compilation vs the Server which waits for 10,000 invocations and uses two threads.
> bool DoEscapeAnalysis = true {C2 product}
In this build the Server VM has escape analysis enabled by default whereas the Client VM cannot enable escape analysis at all. I don't think this is sensible on Oracle's part as whilst escape analysis can improve performance for scientific computing (where many primitives are created within a method and then discarded once a final value has been computed) for other applications escape analysis can lower performance when arguments do escape their methods and are better left on the heap. Slipping in such a change transparently can also be problematic as developers upgrading to a new JVM may see performance degradation in their applications when no visible command line option has changed. Developers should benchmark accordingly when upgrading JVM builds.
< bool RewriteBytecodes = false {pd product}
< bool RewriteFrequentPairs = false {pd product}
> bool RewriteBytecodes = true {pd product}
> bool RewriteFrequentPairs = true {pd product}
An optimisation to rewrite two bytecode operations as one operation.
Super Option Activation
As mentioned earlier some options are super-options and will enable other options. Let's take a look at a common super option: -XX:+AggressiveOpts
The two commands are:
jdk1.6.0_23/bin/java -server -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
jdk1.6.0_23/bin/java -server -XX:+AggressiveOpts -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
here are all the differences:
< bool AggressiveOpts = false {product}
> bool AggressiveOpts := true {product}
< intx AutoBoxCacheMax = 128 {C2 product}
> intx AutoBoxCacheMax = 20000 {C2 product}
< intx BiasedLockingStartupDelay = 4000 {product}
> intx BiasedLockingStartupDelay = 500 {product}
< bool EliminateAutoBox = false {C2 diagnostic}
> bool EliminateAutoBox = true {C2 diagnostic}
< bool OptimizeFill = false {C2 product}
> bool OptimizeFill = true {C2 product}
< bool OptimizeStringConcat = false {C2 product}
> bool OptimizeStringConcat = true {C2 product}
So a number of options have been enable and some others have been given more aggressive values. We know -XX:+AggressiveOpts changes with each JVM build. Let's look at an older build:
(NB. Java6u20 is the oldest build to support this form of option dumping)
jdk1.6.0_20/bin/java -server -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
jdk1.6.0_20/bin/java -server -XX:+AggressiveOpts -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal
< bool AggressiveOpts = false {product}
> bool AggressiveOpts := true {product}
< intx AutoBoxCacheMax = 128 {C2 product}
> intx AutoBoxCacheMax = 20000 {C2 product}
< intx BiasedLockingStartupDelay = 4000 {product}
> intx BiasedLockingStartupDelay = 500 {product}
< bool DoEscapeAnalysis = false {C2 product}
> bool DoEscapeAnalysis = true {C2 product}
< bool EliminateAutoBox = false {C2 diagnostic}
> bool EliminateAutoBox = true {C2 diagnostic}
< bool UseLoopPredicate = false {C2 product}
> bool UseLoopPredicate = true {C2 product}
We can see in 6u20 DoEscapeAnalysis was an AggressiveOpt but in the new build 6u23 DoEscapeAnalysis became the default (as did UseLoopPredicate). Along the same lines OptimizeFill and OptimizeStringConcat may become default values in future builds.
Conclusion
There is enormous scope for coarse and fine grained control of JVM behaviour. The option -XX:+PrintFlagsFinal allows comprehensive reporting of the options and their values. The available options vary by build and JVM type (server or client). Recording and auditing this output is an important step in any Java benchmarking or continuous monitoring exercise. Oracle can surreptitiously enable options in new Java builds which may cause inexplicable changes in performance and behaviour of existing applications.
A method for inspecting the comprehensive set of HotSpot JVM options and some examples comparing different outputs.
Background
The Oracle JVM provides an enormous spectrum of options to control the runtime JVM. These options are given a criminally short and non-comprehensive discussion at the OTN here. OTN divides these options into three categories: Behavioural, Performance and Debugging. This is a useful abstraction but some examples Oracle gives in each category can be misleading due to the overlap between Behavioural and Performance.
The JVM options themselves can be controlled in a number of ways:
- via the command line on JVM startup.
- via JMX for certain options where this is allowed.
- indirectly via the command line by a super-option which then sets other options.
- automatically by the JVM. The JVM has ergonomic capability to detect features of the host and set options accordingly.
-XX:+PrintFlagsFinal
Usage
Let's see this in action! First let's run the following:
$ jdk1.6.0_23/bin/java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
(I have added -XX:+UnlockDiagnosticVMOptions as this unlocks more options for viewing and control. Also I have added -version at the end so Java doesn't complain that it has nothing to run and to supplement the results).
The sysout is quite large so I've saved it here. Firstly you may be surprised at the sheer quantity of JVM options available: 717! That's a lot of configuration! Before we dive into the options lets look at our host specification and the output of the -version option. The host has 8 dual core 64bit AMD Opteron processors running at 3.2GHz so 16 cores in total with 64GB of RAM. The Java -version output shows:
java version "1.6.0_23"
Java(TM) SE Runtime Environment (build 1.6.0_23-b05)
Java HotSpot(TM) Server VM (build 19.0-b09, mixed mode)
this tells us we are running Java 6 update 23 using the Server version of the HotSpot VM in 32bit mode. Now let's look closer at the output. For each option we can see the following columns:
- Datatype. bool for booleans, uintx for unsigned integers etc
- Name
- Assignment. = means this is the default. := means this option was modified from the default value by command line or ergonomics.
- Value
- Category. There are two large categories diagnostic or product. (I find this a better grouping than Behavioural, Performance and Debugging.) and also manageable if this option can be set via JMX. C1 relates to the JIT compiler used in the Client JVM. C2 means the same but for the Server JVM and I suspect pd means Platform Dependent as most pd options are Solaris only.
Let's look closer at the modified options which have the := assignment:
uintx InitialHeapSize := 67108864 {product}
uintx MaxHeapSize := 1073741824 {product}
uintx ParallelGCThreads := 13 {product}
bool PrintFlagsFinal := true {product}
bool UnlockDiagnosticVMOptions := true {diagnostic}
bool UseParallelGC := true {product}
apart from the two flags which I set myself on the command line we can see Java ergonomics has given the heap a sensible range of 64MB to 1GB. The fairly old Parallel Garbage Collector has been chosen with an enormous 13 threads spawned to do the collection. Straightaway we've got a lot more insight into how our JVM is configured and a few ideas for improvements.
Client vs Server JVM Analysis
We know from looking at the -version output Java automatically chose the server JVM instead of the client JVM (Java automatically chooses server if it detects 64bit processors). But how do we know what options are set because Java chose the Server JVM? What options were set because of our host specification? Lets run the following commands and review the output:
$ jdk1.6.0_23/bin/java -client -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
$ jdk1.6.0_23/bin/java -server -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
I have saved the client output here and the diff client server here. Firstly lets look at the output from the Client JVM; it has 661 options, 56 fewer than the Server version. Now let's look solely at the Client options which have been modified, excluding the two options I set on the command line there are only two values which were changed:
uintx InitialHeapSize := 16777216 {product}
uintx MaxHeapSize := 268435456 {product}
so Java has chosen some fairly sensible values for the Client JVM: 16MB initial heap size with a max size of 256MB. There are many entries in the diff file mostly by virtue of the extra options available to the Server JVM or options which relate to memory simply having higher values. Here are the more interesting differences:
< intx CICompilerCount = 1 {product}
> intx CICompilerCount = 2 {product}
< intx CompileThreshold = 1500 {pd product}
> intx CompileThreshold = 10000 {pd product}
The Client VM waits only 1,500 invocations before compiling a method to native code and uses only one thread for compilation vs the Server which waits for 10,000 invocations and uses two threads.
> bool DoEscapeAnalysis = true {C2 product}
In this build the Server VM has escape analysis enabled by default whereas the Client VM cannot enable escape analysis at all. I don't think this is sensible on Oracle's part as whilst escape analysis can improve performance for scientific computing (where many primitives are created within a method and then discarded once a final value has been computed) for other applications escape analysis can lower performance when arguments do escape their methods and are better left on the heap. Slipping in such a change transparently can also be problematic as developers upgrading to a new JVM may see performance degradation in their applications when no visible command line option has changed. Developers should benchmark accordingly when upgrading JVM builds.
< bool RewriteBytecodes = false {pd product}
< bool RewriteFrequentPairs = false {pd product}
> bool RewriteBytecodes = true {pd product}
> bool RewriteFrequentPairs = true {pd product}
An optimisation to rewrite two bytecode operations as one operation.
Super Option Activation
As mentioned earlier some options are super-options and will enable other options. Let's take a look at a common super option: -XX:+AggressiveOpts
The two commands are:
jdk1.6.0_23/bin/java -server -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
jdk1.6.0_23/bin/java -server -XX:+AggressiveOpts -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
here are all the differences:
< bool AggressiveOpts = false {product}
> bool AggressiveOpts := true {product}
< intx AutoBoxCacheMax = 128 {C2 product}
> intx AutoBoxCacheMax = 20000 {C2 product}
< intx BiasedLockingStartupDelay = 4000 {product}
> intx BiasedLockingStartupDelay = 500 {product}
< bool EliminateAutoBox = false {C2 diagnostic}
> bool EliminateAutoBox = true {C2 diagnostic}
< bool OptimizeFill = false {C2 product}
> bool OptimizeFill = true {C2 product}
< bool OptimizeStringConcat = false {C2 product}
> bool OptimizeStringConcat = true {C2 product}
So a number of options have been enable and some others have been given more aggressive values. We know -XX:+AggressiveOpts changes with each JVM build. Let's look at an older build:
(NB. Java6u20 is the oldest build to support this form of option dumping)
jdk1.6.0_20/bin/java -server -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
jdk1.6.0_20/bin/java -server -XX:+AggressiveOpts -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal
< bool AggressiveOpts = false {product}
> bool AggressiveOpts := true {product}
< intx AutoBoxCacheMax = 128 {C2 product}
> intx AutoBoxCacheMax = 20000 {C2 product}
< intx BiasedLockingStartupDelay = 4000 {product}
> intx BiasedLockingStartupDelay = 500 {product}
< bool DoEscapeAnalysis = false {C2 product}
> bool DoEscapeAnalysis = true {C2 product}
< bool EliminateAutoBox = false {C2 diagnostic}
> bool EliminateAutoBox = true {C2 diagnostic}
< bool UseLoopPredicate = false {C2 product}
> bool UseLoopPredicate = true {C2 product}
We can see in 6u20 DoEscapeAnalysis was an AggressiveOpt but in the new build 6u23 DoEscapeAnalysis became the default (as did UseLoopPredicate). Along the same lines OptimizeFill and OptimizeStringConcat may become default values in future builds.
Conclusion
There is enormous scope for coarse and fine grained control of JVM behaviour. The option -XX:+PrintFlagsFinal allows comprehensive reporting of the options and their values. The available options vary by build and JVM type (server or client). Recording and auditing this output is an important step in any Java benchmarking or continuous monitoring exercise. Oracle can surreptitiously enable options in new Java builds which may cause inexplicable changes in performance and behaviour of existing applications.
Update:
ReplyDeleteThere is another option which unlocks further options for reporting and control:
-XX:+UnlockExperimentalVMOptions
Thanks to Tom Poindexter for spotting.
Excellent! Thanks
ReplyDeleteI guess the only way to learn exactly what all of these options do is to download the source code of the JVM from the OpenJDK project and look through the code?
ReplyDeleteYes, along with the source for the JVM, the OpenJDK also has comments explaining each option.
ReplyDeleteThanks for the information
ReplyDeletehttp://extreme-java.blogspot.com
Excellent writeup, lots of useful info. One minor nit though:
ReplyDelete"I don't think this is sensible on Oracle's part as whilst escape analysis can improve performance for scientific computing (where many primitives are created within a method and then discarded once a final value has been computed) for other applications escape analysis can lower performance when arguments do escape their methods and are better left on the heap."
I'm 99% certain that objects that can escape are left on the heap and no optimization is done, and in all the benchmarks I've tried I have never had performance degrede due to +DoEscapeAnalysis.
Due to this caution, it also only helps limited use cases. It is also used for lock elision.
drain bamage,
ReplyDeletefrom benchmarking DoEscapeAnalysis on SpecJVM2008 the statistically meaningful results are:
3/11 showed improvement (scimark.*, sunflow)
1/11 showed regression (compiler)
7/11 within noise allowance (the rest)
If your benchmarking shows no degradation in any suite my conjecture is your benchmarks are focused on scientific computing, small heaps or on hosts with ample spare CPU capacity. My point in the blog was not DoEscapeAnalysis was universally bad but simply I didn't think it's benefits were universally positive to justify Oracle enabling it as a default for everyone.
hi ,
ReplyDeleteDo you know what -Xrs option does? Thanks.
Kumar
fantastic post mate. though we use JVM daily most of us not quite familiar with JVM options and your post help us to get better ideas.
ReplyDeleteJavin
Java debugging tutorial and tips in Eclipse
Good article , I also like 10 JVM Options Java developers should know
ReplyDeleteExtremely helpful!
ReplyDeleteA nice tutorial on
ReplyDeleteJVM Architecture Specification Basic The Heap Area Introduction, teach about the JVM Heap Area in details
http://www.youtube.com/watch?v=c-A7ZzxjWUI
JVM Architecture Specification Basic The Method Area explained, teach about the JVM method area
http://www.youtube.com/watch?v=a5GzF2fSSCE
I think most of these output are useless because in my test flags printed are not affected by setting mad at command line.
ReplyDeleteFor example if I run my JVM with a -XX:+UseConcMarkSweepGC, printed flags do not change while in real life the jvm changes most of memory parameters.
Even setting at command line something like NewRatio = 5 stil give old value
Thanks for providing the information . The articles in your blog helped me a lot for improving the knowledge on the subject. Also check my small collection on this at Java online course blog
ReplyDeleteGood job in presenting the correct content with the clear explanation. The content looks real with valid information.
ReplyDeleteAWS Online Training
AWS Training in Hyderabad
Amazon Web Services Online Training
lampungservice.com
ReplyDeleteserviceiphonebandarlampung.blogspot.com
youtubelampung.blogspot.com
bimbellampung.blogspot.com
bateraitanam.blogspot.com
Sharp
ReplyDeleteLampung
Metroyoutube
youtube
lampung
kuota
Indonesia
Great article ...Thanks for your great information....
ReplyDeleteGCP Training
Google Cloud Platform Training
GCP Online Training
Google Cloud Platform Training In Hyderabad
Very Nice article, Thanks For Sharing
ReplyDeleteHere a related Stuff:
Power Bi Training In Hyderabad
Power Bi Online Training
Power Bi Training In Ameerpet
ebay quickbooks integration
ReplyDeleteThis is really great informative blog. Keep sharing.
ReplyDeleteGCP Online Training
Google Cloud Platform Training In Hyderabad
Thanks for sharing this information. I really Like Very Much.
ReplyDeletemulesoft online training
workday online training
sap lumira online training
online it training institute
I just loved your article on the beginners guide to starting a blog.If somebody take this blog article seriously in their life, he/she can earn his living by doing blogging.thank you for thizs article. devops online training
ReplyDeleteI am reading your post from the beginning, it was so interesting to read & I feel thanks to you for posting such a good blog, keep updates regularly..
ReplyDeletemulesoft 4 training
This is very helpful writing for blog writer and also after read you post i am learn more of blog writing thank you...
ReplyDeleteData Science Training in Hyderabad
Hadoop Training in Hyderabad
selenium Online Training in Hyderabad
Devops Training in Hyderabad
Informatica Online Training in Hyderabad
Tableau Online Training in Hyderabad
ReplyDeleteThank you for sharing such a great information.Its really nice and informative.hope more posts from you. I also want to share some information recently i have gone through and i had find the one of the best mulesoft 4 self training
Thanks for Sharing This Article.It is very so much valuable content. I hope these Commenting lists will help to my website
ReplyDeletetop microservices online training
Thanks for Sharing This Article.It is very so much valuable content. I hope these Commenting lists will help to my website
ReplyDeletetop servicenow online training
thanks for providing such a great article, this article is very help full for me, a lot of thanks sir
ReplyDeletefinance project for mba
finance topics for mba project
Ignou Synopsis
hadoop training in hyderabad i am enjoyed while reading your blog .thanks for sharing and keep sharing
ReplyDelete
ReplyDeleteWow. That is so elegant and logical and clearly explained. Brilliantly goes through what could be a complex process and makes it obvious.I want to refer about the best tableau online course
very nice blogs!!! i have to learning for lot of information for this sites...Sharing for wonderful information. Thanks for sharing this valuable information to our vision. You have posted a trust worthy blog keep sharing
ReplyDeleteDigital Marketing In Telugu
Digital Marketing In Hyderabad
internet marketing
Digital marketing
Digital Marketing Strategy
I have saved this link and will return in a Income tax filingcouple of months, when I need to build my first blog. Thank you for the information.
ReplyDeleteThis is the first occasion when I read your blog and appreciate that you have posted on this. truly discovered valuable. Keep refreshed.
ReplyDeletesatta result
satta king
satta chart
satta matka result
satta matka
satta king online Result
satta
gali satta
disawar result
Thanks for Sharing This Article.It is very so much valuable content. I hope these Commenting lists will help to my website
ReplyDeleteservicenow online training
best servicenow online training
top servicenow online training