I've got short-living applications which usually (but not always) do not need any GC (fits in heap, epsilon GC proves this by not causing an OOM).
Interestingly, G1 still kicks in very early even though there's still plenty of heap free:
[0.868s][info ][gc,start ] GC(0) Pause Young (Normal) (G1 Evacuation Pause)
[0.869s][info ][gc,task ] GC(0) Using 13 workers of 13 for evacuation
[0.872s][info ][gc,phases ] GC(0) Pre Evacuate Collection Set: 0.0ms
[0.873s][info ][gc,phases ] GC(0) Evacuate Collection Set: 2.8ms
[0.873s][info ][gc,phases ] GC(0) Post Evacuate Collection Set: 0.4ms
[0.873s][info ][gc,phases ] GC(0) Other: 1.0ms
[0.873s][info ][gc,heap ] GC(0) Eden regions: 51->0(45)
[0.873s][info ][gc,heap ] GC(0) Survivor regions: 0->7(7)
[0.873s][info ][gc,heap ] GC(0) Old regions: 0->2
[0.873s][info ][gc,heap ] GC(0) Humongous regions: 4->2
[0.873s][info ][gc,metaspace ] GC(0) Metaspace: 15608K->15608K(1062912K)
[0.874s][info ][gc ] GC(0) Pause Young (Normal) (G1 Evacuation Pause) 55M->10M(1024M) 5.582ms
[0.874s][info ][gc,cpu ] GC(0) User=0.00s Sys=0.00s Real=0.01s
[...]
It makes me wonder why GC runs here at all as heap is only 55MB.
In total I have usually 10-15 GC runs which aggregate to a consumed user cpu time of ~1 second which I'd like to avoid.
JVM: openjdk version "11.0.16" 2022-07-19
JVM ARGS: -Xms1g -Xmx2g -XX:+PrintGCDetails -Xlog:gc+cpu=info -Xlog:gc+heap+exit
Question:
How can I tune G1 (jdk 11) to kick in as late as possible (e.g. when heap/eden is 90% full) to ideally avoid any GC pauses/runs in most of my cases?
Increasing -XX:InitiatingHeapOccupancyPercent
(e.g. to 90%) did not help in my case.
EDIT:
Try it out by yourself by executing this java class on your jvm:
public class GCTest {
public static void main(String[] args) {
java.util.Map<String,byte[]> map = new java.util.HashMap<>();
for(int i=0;i<1_000_000;i++)
map.put(i+"", new byte[i % 256]);
System.out.println(map.size());
}
}
This application consumes about 260MB heap and runs less than 500ms.
When started with the following jvm arguments:
-Xms1g -Xmx2g -XX:+PrintGCDetails -Xlog:gc+cpu=info -Xlog:gc+heap+exit
you will get ~5-6 GC runs (tested with java 11+16 hotspot vm) .
GC Epsilon tests clearly shows that it can run without any GCing.
Challenge:
Can you find jvm arguments which will force G1 to not do any GCing here?