invoking java gc through bash

23 November 2016

Sometimes Java processes start accumulating memory over time and do not give them back to the OS. In previous versions of Java, this was a limitation of the JVM. In Java 8 and newer, with the arrival of the G1 garbage collector, the JVM releases memory back to the OS after a GC run.

Now since this is possible, calling a GC, although there is still free memory available becomes a different meaning. On the other hand most application aren’t build with that in mind, so they do not offer any public interface to trigger a GC.

Luckily, the Oracle JDK has a tool for that call “jcmd”.

/usr/lib/java/jdk-1.8.0-66_H02-linux_x64/bin/jcmd {PID} GC.run

Now, to invoke this regularly and not only invoking one, but all engines running this application jar, I used the following script and hooked that into the crontab.

#!/bin/bash

/usr/lib/java/jdk-1.8.0-66_H02-linux_x64/bin/jcmd | grep app.jar | cut --delimiter=' ' -f 1 | while read -r line
do
   /usr/lib/java/jdk-1.8.0-66_H02-linux_x64/bin/jcmd $line GC.run
   sleep 1;
done

Now, every couple of hours, a GC is invoked on the JVM, so the memory bloat stays within reason.