I have java tomcat application that is serving web requests. It should execute each web request as fast as possible. Every second I receive about 4 requests. I've done a serious job optimizing the servlet. Now it generally serves each request in less then 100ms. But sometimes requests are served after 200ms. If I rerun these slow requests, they are again faster then 100ms. I've enabled GC logging and found out that almost always before each "slow" request I have CMS-initial-mark that freezes JVM:
[GC [1 CMS-initial-mark: 1411302K(1415616K)] 1912881K(2029056K), 0.3224110 secs]
[Times: user=0.00 sys=0.00, real=0.32 secs]
And mostly all the time request execution time is the same order of magnitude as GC collection time. I use 8-core server with 32GB of RAM. My JVM settings are:
-Xmx2G -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails.
My OS is latest Debian with default settings. No other processes are running except mongodb. The only process that is shown in top command output is java and it uses ~100% of CPU (I have 8 CPUs, so it is only 1/8 of load).
How can I overcome this problem? What else can be diagnosed?