-
Enhancement
-
Resolution: Unresolved
-
P4
-
None
Back to back humongous allocations with no other garbage cause G1 to eventually trigger a Full GC, instead of the expected behaviour of triggering a concurrent cycle as soon as the IHOP is breached.
Repro:
```
public class HumongousGc {
public static void main(String[] args) throws Exception {
for (int i = 0; i < 100; i++) {
Integer[] humongous = new Integer[10_000_000];
System.out.println(i);
Thread.sleep(100);
}
}
}
```
```
java -Xlog:gc -Xms1G -Xmx1G HumongousGc.java
...
35
36
37
[4.964s][info][gc] GC(4) Pause Young (Prepare Mixed) (G1 Humongous Allocation) 1017M->1017M(1024M) 1.828ms
[4.972s][info][gc] GC(5) Pause Full (G1 Compaction Pause) 1017M->2M(1024M) 8.451ms
```
It seems that G1Policy::need_to_start_conc_mark does not start a concurrent mark if about_to_start_mixed_phase() is true, but there's nothing guaranteeing that the mixed phase starts in a timely fashion, and in this case the mixed phase is delayed indefinitely, so we never get our concurrent mark, and have to fall back to an expensive Full GC.
I found this issue while investigating a problem with GC behaviour in a real application, but I don't know yet if this is the problem we saw in production, so I don't know how realistic this scenario is.
Repro:
```
public class HumongousGc {
public static void main(String[] args) throws Exception {
for (int i = 0; i < 100; i++) {
Integer[] humongous = new Integer[10_000_000];
System.out.println(i);
Thread.sleep(100);
}
}
}
```
```
java -Xlog:gc -Xms1G -Xmx1G HumongousGc.java
...
35
36
37
[4.964s][info][gc] GC(4) Pause Young (Prepare Mixed) (G1 Humongous Allocation) 1017M->1017M(1024M) 1.828ms
[4.972s][info][gc] GC(5) Pause Full (G1 Compaction Pause) 1017M->2M(1024M) 8.451ms
```
It seems that G1Policy::need_to_start_conc_mark does not start a concurrent mark if about_to_start_mixed_phase() is true, but there's nothing guaranteeing that the mixed phase starts in a timely fashion, and in this case the mixed phase is delayed indefinitely, so we never get our concurrent mark, and have to fall back to an expensive Full GC.
I found this issue while investigating a problem with GC behaviour in a real application, but I don't know yet if this is the problem we saw in production, so I don't know how realistic this scenario is.