Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Garbage Collector time limit

Tags:

Situation

I am developing a client for a contest in Java, and whenever I receive a request, I have two seconds to respond. The time after the response until the next request is unknown.

Sometimes, finding the right response takes nearly 2 seconds, and sometimes it's only a matter of a few milliseconds. The issue is when garbage collection happens in one of the longer calculations (which also allocates a lot of objects) right towards the end of the two seconds, and thus the response is sent too late and I get disqualified.

Using verbose gc output I identified that the gc usually takes about 0.6s, even though I tried to limit it lower. I also tried to invoke System.gc() on the shorter calculations (since I am sure I have about 1.8s where I don't need to do anything), but it took 1-3s, which is not safe either.

My program has very few long-living objects, most live shorter than a second.

Specs

I know that the program will always run on the same machine with these resources available:

  • 64 bit Ubuntu
  • openjdk:8u151-jre
  • one core of an Intel® Xeon® Prozessor E5-2620 v4
  • 1.5 GB of RAM

My current jvm parameters:

java -Dfile.encoding=UTF-8 \
  -XX:MaxGCPauseMillis=200 \
  -XX:GCPauseIntervalMillis=2050 \
  -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled \
  -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 \
  -XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark \
  -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps

Ideas

  • Can I somehow tell the gc that it should collect some garbage now, but only for about 1.5 seconds?
  • Is there a System.gc() equivalent that only works with the young objects and doesn't check the tenured generation?
  • Can the jvm parameters be optimised to achieve better results?
like image 350
xeruf Avatar asked Feb 26 '18 13:02

xeruf


2 Answers

Here are things that you could try to reduce pauses:

  • Try the G1 collector instead of CMS
  • Use more realistic GC goals. The current goals allow 200ms of stop-the-world GC time every 2 seconds. Increase MaxGCPauseMillis and/or reduce GCPauseIntervalMillis.
  • Add another core so that the JVM is able to GC in parallel with your application.
  • Reduce CMSInitiatingOccupancyFraction so that the GC triggers the background GC threads when the heap is less full.
  • Reduce the rate at which your application generates garbage.
  • Tune your application algorithms so that there is more free time for background GC (on your single core).
like image 137
Stephen C Avatar answered Oct 10 '22 05:10

Stephen C


After a lot of experimenting, I found the flags I needed and want to share this knowledge now:

  • -XX:+UseConcMarkSweepGC - after comparing log results of G1 and CMS for my usecase I determined t CMS pause times are lower, additionally it still supports single-threaded collections
  • -XX:+ExplicitGCInvokesConcurrent Upon calling System.gc() not a Full GC will be invoked, but a standard one.
  • -XX:NewRatio=1 the size ratio of old generation to young generation, this is the lowest value since I have very few long-living objects
  • -mx800m -ms800m reduces and fixes the memory size, thus collections will occur more frequent and take less time. Trades throughput for responsiveness.
  • -XX:-UseParNewGC Disables parallelization for collecting the young generation. This was the dealbreaker and reduced the GC stop-the-world times from 0.2-0.5s to 0.02-0.2s, since i only have one core available. (Combining this with CMS is deprecated and subject to be removed in newer Java versions)

Using these parameters I could reduce GC pause times from varying between 0.4s and 3s down to consistently less than 0.2 seconds. And for completeness, these flags were the most useful for debugging:

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution

Please don't forget that these are optimised for very specific requirements: Onle one core available, a lot of young garbage, no old collections, very low stop-the-world-pauses

This is a little cheat sheet I can recommend for further reading: http://blog.ragozin.info/2016/10/hotspot-jvm-garbage-collection-options.html

like image 24
xeruf Avatar answered Oct 10 '22 03:10

xeruf