I am in performance testing. I have seen many blogs regarding setting the value of -Xmx and -Xmx. I am little confused as some says it is good to have -Xms=-Xmx. I am on a project where on production server there are about 8-15K peoples online i.e it is always on high load. What should be the optimized setting for -Xms and -Xmx?
-
It would be depend on your requirement and RAM size :P – Sachin Mar 11 '13 at 12:28
-
1setting -Xms=-Xmx does not depend on RAM. – ajay Mar 11 '13 at 12:52
1 Answers
Sadly this is a big topic in Java, and the more tuning that you do here for a specific release of your code then the more risk you will have of having to retune it when you make your next release. Several consultancies specialise in this type of stuff because of its complexity, plus we have now see the release of Zing which is a commercial JVM intended to manage this for us (by throwing spare CPUs at the problem of GC management). However, that said there are some settings that nearly always help.
Your goal is to avoid 'stop the world' events within the JVM, ones that will pause all threads while the JVM goes off to do work. Setting Xms and Xmx to the same value help here because having them different tells the JVM to start with a small heap and to then resize as it needs. Unfortunately this resizing is a stop the world event that causes large copies of objects within the heap and full GC. Expensive.
Your next goal should be to avoid objects getting tenured prematurely. The JVM is very efficient at creating lots of objects, and then releasing them soon afterwards. The problems occur when the objects are 'too big', they are held on for a while or they are more of them than fit in the eden space (a region of the heap reserved for new objects).
In general I like to increase the amount of the heap given to the young generations, and as much as possible reduce the size of the total heap. Smaller heaps are faster in Java, but you risk running out of memory. So I then spend most of my time optimising my algorithms and cleaning the code. If that does not give me the performance that I require then I instruct the JVM to write to log file its GC activity (details here Analyze GC logs for Sun Hotspots, JVM 6). My goal is to watch how much data is getting tenured.
Lastly you should read up on the different GC algorithms and select the one supported by your JVM that gives you the best performance. In general I would stay away from the G1 collector, it does not perform very well and was discussed at QCon as being a 'failed experiment' and the GC implementors are moving on to other approaches.
-
An area that you may not have considered is pinning your Java process to a CPU. This is extremely powerful you are running on a multi core system that is spending a lot of time shuttling data between cores that do not need to be shuttled. This alone can speed algorithms up by 5 times or more. But it does depend on your circumstances, Martin Thompson has written a lot about this topic. For more have a read of http://mechanical-sympathy.blogspot.co.uk/2011/07/processor-affinity-part-1.html. – Chris K Mar 11 '13 at 12:57