Tuesday, September 24, 2013

JVM Params Everyone Should Have in Production

I know I did not published anything useful in last months. As a matter of fact, I had this blog post almost ready for quite a long time. Unfortunately, I have a lot to say on procrastination but I will leave it for tomorrow:) Anyway after the JVM hotspot sessions in JavaOne and after a direct question in JClarity friends newsletter and after suffering from severe jet lag I have decided to finalise this post. 


When talking about JVM configuration I find myself breaking the DRY principle so I it about time to write a blog post on this topic. Following list of a the must have JVM params for (almost) every server installation:

(parameterised values are specified in curly braces)

-Xms{#MB}m -Xmx{#MB}m
-XX:PermSize={#MB}m -XX:MaxPermSize={#MB}m
-XX:+HeapDumpOnOutOfMemoryError
-XX:+PrintFlagsFinal
-server
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps 

-XX:+PrintTenuringDistribution
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintGCApplicationConcurrentTime
 -XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles={#files}
-XX:GCLogFileSize={#MB}M
-Xloggc:{some gc log file}.gc 

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port={a port}
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false




Memory params (blue): You probably need to set minimal and maximal heap size to suite your needs. In most cases ms=mx but that is not always the case. IMO it is really important to have a memory dump whenever you encounter an OutOfMemoryError mainly if you want to be able to isolate fast "spike" memory depletion bugs. 

-XX:+PrintFlagsFinal - Displays the configuration of the JVM all parameters available with their default value or the overridden one.
-server is not really needed it is just a safety net to make sure you are not running a client compiler or something stupid like that :) 

GC logging configuration(green): If you want to be able to estimate GC efficiency GC logging is the way. Starting from J7 log file rotation is supported use it to keep at least two-four weeks of GC activity.

Remote JMX configuration(purple) : Opening a JMX port for remote monitoring can help you debug and monitor your server with tools like VisualVM and JConsole. If security is an issue you may also require password and encrypt communications. 

A few more notes:
1. I am not getting into GC tuning configuration params as these params vary from one application to another and tuning GC is not in the scope of this post. However if you are using CMS I think that
-XX:+ExplicitGCInvokesConcurrent should be your default unless proven otherwise.
2. J8 has the new MetaSpace instead of the PermGen space so perm gen params are no longer required.

What is your common set of params ?

6 comments:

Unknown said...

You should be careful to only disable JMX authentication if you're exposing JMX on a non-public interface/port. Of course this can be addressed with firewalling.

Lifey said...

I agree, Usually servers are behind firewall so the port will be blocked anyway. I doubt that any enterprise will open a port in a firewall for JMX monitoring. So it is pointless to go through the hassle of encrypting and authenticating....

Anonymous said...

A whole bunch of GC params -

http://orangemile.blogspot.com/2013/10/gc-parameters.html

Unknown said...

It is quite a strong statement: "must have".

You should actually use as few JVM flags as required. So if you know, that default PermGen size is enough for you, why add the extra flag ?

JVM flags in startup scripts have this weird tendency to stick around much longer than actually needed. They often become obsolete when new versions of JVM are available.

But I do STRONGLY agree on all the GC flags. They should always be there so we have logs available from when the problem occured. Adding them after one has happened is not a good practice.

Also some people say that they don't enable GC logging because of performance reasons... well, I would just direct them to Kirk Pepperdine's JVM Tunning workshop :)

Lifey said...

"Must have" is related to my point of view. Of course you can disagree with that. There is a huge number of parameters that one can use for his JVM. For each one of the parameters stated in the above list I have a strong reason to use add it. The flags related to JMX remote monitoring the flags related to GC logging the HeapDumpOnOOM etc.
Regarding PermGen size Most of the projects I have seen require to increased the permgen size. Stating it is like declaring that you acknowledge that there is such a space and you know how much of it you need :)

Lifey said...
This comment has been removed by the author.