Thursday, September 3, 2015

Performance Tuning JVM

Performance tuning is no easy task, and when you are trying to improve application there are many aspects to it. The various levels which can be tuned include: Operating System, Application Server, Database, and Application Configurations/Code. The first place to look when planning to improve performance is to improve the performance of your algorithms, this can be in the application code whether it's in the database or not. Having an algorithm that runs O(n^3) or polynomial then finding a way to reduce it to a order to linear or logarithmic this will beat most any other changes that anywhere else that could be made. However here we will talk specifically about the JVM when running Oracle WebLogic 12c.

Memory Options
If you've had any experience with the JVM then you likely know about a few java options available to you. The usual ones people set are: -Xms, -Xmx, and -XX:MaxPermSize. One thing to note is that with Java 8 PermGen has been replaced with Metaspace as mentioned in this post. While the official minimum amount of memory recommended for WebLogic 12c is 4GB, I would recommend at least 8GB for most applications, but many cases there may be a need for even more memory. This is completely dependent upon the applications running within WebLogic. The second recommendation is that whatever the amount of memory is designated for the maximum amount of memory through Xmx, the same amount should be set for the minimum using Xms . This saves the JVM from wasting time cycles on deallocating memory back to the system.
With respect to MetaSpace a similar option is now available -XX:MaxMetaspaceSizewhich will allow a limit on the new space. Just as with the JVM Heap we want to limit the size of the Metaspace usually a 1G is plenty of space and depending on your application may even be overkill. The important part however is to make sure that there is a limit. Now that we have our various spaces in memory we need to look at how to manage it.

Garbage Collectors
There are a number of different garbage collectors available including: Concurrent Mark Sweep (CMS), ParallelGC, and Garbage First (G1GC). G1GC the newest of the bunch, and it certainly has a lot of advantages many of which can be found here. However, it is still not ready for the lime light. It was introduced in an update to Java 7, and is currently targeted to be the default for Java 9; it could still be pushed back if it still isn't considered stable enough. Concurrent Mark Sweep is an older collector is used to focus on lower pause times which G1GC is planned to replace, and ParallelGC is considered the throughput collector. Once again there is no really solid answer as to which you should use, but from working with clients, ParallelGC has been the most dependable when it came to heavier load tests. While I wouldn't say to use G1GC right now, there are some fixes coming which may change my mind in the future. To use any of these garbage collectors you will need the following commands:
G1GC: -XX:+UseG1GC
ParallelGC: -XX:+UseParallelGC
CMS: -XX:+UseConcMarkSweepGC

Once a garbage collector is selected there are a number of options specific to them which can be explored, and should be explored to find further improvements.

Additional Options
While there are many tweakable options, there are only a few I would look into beside the ones mentioned above. -XX:+ScavengeBeforeFullGC is a setting that deals with performing a scavenge before a full garbage collection, and I would almost alway use unless there is a specific performance hit seen from its use. -XX:MaxTenuringThreshold can be tweaked to different numbers and can be useful depending on long your application tends to hold onto certain information. -XX:+AlwaysPreTouch prepares handles for paging in the beginning, and while it has a performance hit on startup tends to result in quicker memory accesses later. Finally, -XX:+ParallelRefProcEnabled allows for parallel as opposed to serial reference processing as part of the garbage collection process, another flag that I would highly recommend enabling. 

Happy Tuning!

No comments: