Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Appropriate JVM/GC tuning for 4GB JVM with 3GB cache

I am looking for the appropriate settings to configure the JVM for a web application. I have read about old/young/perm generation, but I have trouble using those parameters at best for this configuration.

Out of the 4 GB, around 3 GB are used for a cache (applicative cache using EhCache), so I'm looking for the best set up considering that. FYI, the cache is static during the lifetime of the application (loaded from disk, never expires), but heavily used.

I have profiled my application already, and I have performed optimization regarding the DB queries, the application's architecture, the cache size, etc... I am just looking for JVM configuration advices here. I have measured 99% throughput for the Garbage Collector, and 6-8s pauses when the Full GC runs (approximately once every 1/2h).

Here are the current JVM parameters:

-XX:+UseParallelGC -XX:+AggressiveHeap -Xms2048m -Xmx4096m
-XX:NewSize=64m -XX:PermSize=64m -XX:MaxPermSize=512m
-verbose:gc -XX:+PrintGCDetails -Xloggc:gc.log

Those parameters may be completely off because they have been written a long time ago... Before the application became that big.

I am using Java 1.5 64 bits.

Do you see any possible improvements?

Edit: the machine has 4 cores.

like image 719
Matthieu Napoli Avatar asked Jan 10 '12 13:01

Matthieu Napoli


People also ask

How much memory should I allocate to JVM?

Therefore we recommended that physical memory availability for each JVM be 4096 MB;0.5 GB is for JVM allocation and 512 MB is for overhead. This simplified calculation means that a 64-bit system with 16 GB physical memory can run 3 JVMs.

What is the default GC in Java 11?

The default garbage collector in Java 11 is the G1 garbage collector (G1GC). The aim of G1GC is to strike a balance between latency and throughput. The G1 garbage collector attempts to achieve high throughput by meeting pause time goals with high probability.

What is the default GC in Java 8?

For example on Java 8, the default GC is Parallel GC, while on Java 11 the default is G1 GC.

What is GC tuning?

GC tuning is a process of optimizing GC parameters and heap generation sizes to fit the runtime usage of JVM memory, and has proven itself an effective way to reduce NameNode pause time, which in turn decreases request latency and increases throughput.


1 Answers

-XX:+UseParallel*Old*GC should speed up the Full GCs on a multi core machine.

You could also profile with different NewRatio values. Your cached objects will live in the tenured generation so profile it with -XX:NewRatio=7 and then again with some higher and lower values.

You may not be able to accurately replicate realistic use during profiling, so make sure you monitor GC when it is in real life use and then you can make minor changes (e.g. to survivor space etc) and see what effect they have.

Old advice was not to use AggressiveHeap with Xms and Xmx, I am not sure if that is still true.

Edit: Please let us know which OS/hardware platform you are deployed on.

Full collections every 30 mins indicates the old generation is quite full. A high value for newRatio will give it more space at the expense of the young gen. Can you give the JVM more than 4g or are you limited to that?

It would also be useful to know what your goals / non functional requirements are. Do you want to avoid these 6 / 7 second pauses at the risk of lower throughput or are those pauses an acceptable compromise for highest possible throughput?

If you want to minimise the pauses, try the CMS collector by removing both

-XX:+UseParallelGC -XX:+UseParallelOldGC 

and adding

-XX:+UseConcMarkSweepGC -XX:+UseParNewGC

Profile with that with various NewRatio values and see how you get on.

One downside of the CMS collector is that unlike the parallel old and serial collectors, it doesn't compact the old generation. If the old generation gets too fragmented and a minor collection needs to promote a lot of objects to the old gen at once, a full serial collection may be invoked which could mean a long pause. (I've seen this once in prod but with the IBM JVM which went out of memory instead of invoking a compacting collection!)

This might not be a problem for you - it depends on the nature of the application - but you can insure against it by restarting nightly or weekly.

like image 113
Paul Medcraft Avatar answered Sep 17 '22 22:09

Paul Medcraft