So the problem is that I would like to disable explicit GC to make sure no library can "force" FullGC with System.gc()
. But I would like to still retain some control of when FullGC will happen. Is this doable? I mean is it possible to force (or strongly suggest) FullGC via JMX or some Tomcat management tools? Or maybe some command-line in cron?
The motivation of forcing FullGC is to make sure it doesn't happen in the middle of the day.
To my understanding FullGC will happen randomly with -XX:+DisableExplicitGC
option. It will happen when Java will feel there is need to do this.
Or maybe there is some way to suggest Java something like "don't do FullGC from 7:00 to 16:00"?
Full GC can be forced even with -XX:+DisableExplicitGC
by invoking a heap inspection operation like GC.class_histogram
MBean: com.sun.management:type=DiagnosticCommand
Operation: gcClassHistogram
jcmd <pid> GC.class_histogram
Alternatively, you can intercept System.gc()
calls by preloading a shared library with a custom JVM_GC
implementation.
Here is an example:
#define _GNU_SOURCE
#include <time.h>
#include <dlfcn.h>
void JVM_GC() {
time_t timestamp = time(NULL);
struct tm t;
localtime_r(×tamp, &t);
// Don't do Full GC between 7:00 and 16:00
if (t.tm_hour >= 7 && t.tm_hour < 16) {
return;
}
void* original_jvm_gc = dlsym(RTLD_NEXT, "JVM_GC");
if (original_jvm_gc != NULL) {
((void (*)()) original_jvm_gc)();
}
}
Compile:
gcc -O2 -fPIC -shared -o librestrictgc.so restrictgc.c -ldl
Run:
LD_PRELOAD=/path/to/librestrictgc.so java <args>