When and why you should run when someone (including myself) recommends a certain set of JVM settings

by kai on 30/12/2013



This is part two of a loosely connected series of blog posts dealing with JVM settings. Make sure you check out the first post titled “JVM memory settings for Railo (and Adobe ColdFusion) on Tomcat” before continuing to get an idea of the overall context of this series.

Today’s post is about why generic recommendations for JVM settings are almost every time going to fail you and why I personally try to avoid having to provide advise along those lines.

Quite often one sees questions like:

My JVM settings are X,Y and Z. I want to change them to: JAVA_OPTS=”-Xms4096m -Xmx4096m -XX:MaxPermSize=256m -javaagent:lib/railo-inst.jar. Is this any good? Please help!

or

I found JAVA_OPTS=”-javaagent:/usr/local/tomcat/lib/railo-inst.jar -Xms512m -Xmx1424m -XX:MaxPermSize=512m -XX:NewSize=64m -XX:MaxNewSize=64m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled” on a blog, now my server is {fast|slow|dead|hanging|…}. Why? Can you fix or improve it?

popping up on mailing lists.

I usually try to avoid answering them – for a variety of reasons:

  1. JVM performance tuning is a very, very, very small area of performance tuning for any CFML or Java server. Usually there are easier gains and wins to be made while looking at other elements of performance tuning, such as DB access, overall machine performance, network and SAN issues, CFML server settings or general caching approaches. JVM performance tuning beyond basic memory adjustment is a very niche thing and should be used to fix certain types of issues – for instance “inexplicable” delays of a CFML server serving requests.
  2. 95% of JVM settings are not RIGHT or WRONG. There is no black and white, only various shades of gray in this. What works well for one combination of hardware, software stack (OS, Java server, JVM), CFML/Java application and usage pattern will most guaranteed not be the best solution for another server where only one of the aforementioned parameters is different. The only way to find the “right” (or to be more precise: “locally optimised”) JVM settings is by going through a regime of:
    • (Load) testing and measuring
    • Evaluating the results
    • Change one setting
    • Rinse and Repeat and determine if it was a change to the better or the worse
  3. The reasons outlined in 2. mean: there’s no globally optimised JVM setting one could possibly recommend. I can’t, I won’t and I strongly believe no one can do that.

Sometimes, people respond to questions/threads as above along the lines: “Yeah, that’s fine, but you should set XYZ=256m instead” knowing nothing about the original poster’s environment or situation. Frankly, that’s bollocks and contributes to the weird impression people gained over the last few years that JVM tuning is one of the “dark arts”.

Similarly dangerous are scenarios in which people post supposedly awesome JVM settings on their blogs and advertise them as the best thing since the invention of sliced bread (or Jet Planes). This is dangerous because even though those settings might actually work really well for their use case they can never be generic enough to be advertised as such.

Usually either of the above are well intended and that has to be acknowledged and appreciated. Well, that is until the advice is actually not helpful or people can’t really explain what they’re are suggesting and the JVM settings become a dark art. I’d rather see us as a community provide people with the knowledge of being able to help themselves and understand what’s actually happening on their system.

All that being said, what are you supposed to do then? There are some obvious generic recommendations that can be made. Those entail parameters such as overall memory sizing. Or the pros and cons of certain garbage collection strategies or what one can do to mitigate the risks of running into, let’s say… PermGen Out-Of-Memory situations. But that’s about it. From there onwards, proper advise can’t be given in a generic way without having to have a look at the specifics of one’s environment.

I will elaborate on some of the more generic recommendations in further parts of this series. If you want to know more, you can also attend cf.Objective() 2014 and/or Scotch on the Rocks 2014 at which I will talk about those and other subjects related to the JVM.

Comments on this entry are closed.

Previous post:

Next post: