Summary
-------
The current JMX memory pool and collector definitions for the G1 collector don't reflect reality well, thus should be replaced with ones that do. I expect to ask for a backport to a JDK 11 update release, and possibly JDK 8, so users can transition their code independent of a JDK 8/10 to JDK 11 migration.
Problem
-------
See Summary.
Solution
--------
An attempt was made to merge old and new definitions in a compatible way, but foundered on the problem of iterating over G1s GarbageCollectorMXBeans: old and new versions would overlap functionality in ways that cannot be reconciled. The new definitions will be the default, but for compatibility, a new -XX:+G1UseLegacyMonitoring Hotspot switch will revert to the current definitions.
The three existing MemoryPoolMXBeans
```
G1 Eden Space : eden
G1 Survivor Space : survivor space
G1 Old Gen : old generation, including humongous regions
```
are replaced with six
```
G1 Eden Space : eden
G1 Survivor Space : survivor space
G1 Old Space : old generation (now a "space" rather than a "gen", and does not include regions containing humongous or archive objects)
G1 Humongous Space: humongous space (regions containing humongous objects)
G1 Archive Space : class data sharing metadata space, a read-only space
G1 Free Space : free space cache
```
Somewhat non-intuitively, the new G1 Free Space does *not* represent the part of the heap that is not in the other five spaces, rather it represents the part of the heap that G1 uses as a free region cache.
Both the new G1 Old Space and G1 Humongous Space have usage thresholds enabled. In the legacy model, only the G1 Old Gen has thresholds enabled.
The six new memory pools are address-wise disjoint, even though the G1 Archive Space is logically part of the G1 Old Space. Existing Java code that uses memory pools assumes that all memory pools are address-wise disjoint.
Three invariants exist for the Serial, Parallel and legacy G1 models.
1. The sum of the positive memory pool Usage.max sub-attributes is equal to the maximum available Java heap memory. it may not be exactly -Xmx, so we call it MaxHeapSize in this document. It is the value of the "max" property of the [MemoryUsage](https://docs.oracle.com/en/java/javase/15/docs/api/java.management/java/lang/management/MemoryUsage.html) result of calling [MemoryMXBean.getHeapMemoryUsage](https://docs.oracle.com/en/java/javase/15/docs/api/java.management/java/lang/management/MemoryMXBean.html#getHeapMemoryUsage()).
2. The sum of the positive Usage.max sub-attribute values minus the sum of the Usage.committed sub-attribute values is the total uncommitted memory.
3. The sum of all heap memory pools' positive max values minus the sum of their used values is the total free memory.
In order to conform to these invariants, the G1 legacy model sets all max values to undefined, except for G1 Old Gen, whose max value is MaxHeapSize.
In the new G1 model, the first and second invariants do not hold. Rather, memory pool max values are defined for the G1 Eden Space, G1 Old Space, G1 Archive Space, and G1 Free Space, and are undefined (i.e., -1) for the G1 Survivor Space and G1 Humongous Space.
In both models, total committed memory is the value of the "committed" property of the [MemoryUsage](https://docs.oracle.com/en/java/javase/15/docs/api/java.management/java/lang/management/MemoryUsage.html) result of calling [MemoryMXBean.getHeapMemoryUsage](https://docs.oracle.com/en/java/javase/15/docs/api/java.management/java/lang/management/MemoryMXBean.html#getHeapMemoryUsage()). Uncommitted memory is just (MaxHeapSize - that "committed" value).
In the new G1 model, the third invariant does not hold because max values are space-specific. The current total free space, both reserved and committed, is (MaxHeapSize - the above "committed" value + the G1 Free Space committed value).
The committed and used sub-attribute values for each of the new G1 pools, other than the G1 Free Space, are the same, net of their regions' internal free space. used values may not include internal allocation region free space and are thus always less than or equal to committed values, which latter are an integral multiple of the region size. Inversely, the G1 Free Space used value may include allocation regions' internal free space, and thus will always be greater than or equal to its committed value.
If defined, max sub-attribute values are approximations. An attempt is made to make them be the maximum sizes that can be reached from the current heap state, so max values may vary over time.
Since the new G1 Archive Space is loaded during JVM initialization and does not change after that, its committed, used, and max values are the same as its init value.
For the initial implementation,
1. The G1 Eden Space max value is the value implied by G1MaxNewSizePercent and MaxHeapSize.
2. The G1 Survivor Space max value is undefined.
3. The G1 Old Space max value is (MaxHeapSize - the G1 Archive Space max value - the value implied by G1NewSizePercent and MaxHeapSize). The idea is that the G1 Survivor Space and G1 Humongous Space sizes could go to zero if all objects in them were tenured.
4. The G1 Archive Space max value is the same as its init value.
5. The G1 Humongous Space max value is undefined.
6. The G1 Free Space max value is (MaxHeapSize - the G1 Archive space max value - the value implied by G1NewSizePercent and MaxHeapSize). This is the the same definition as the one for G1 Old Space, but the idea here is that the heap could become completely empty, except for objects in G1 Archive Space and a minimal G1 Eden Space.
----------
The two existing GarbageCollectorMXBeans
```
G1 Young Generation : incremental collector, both pure young and mixed collections
G1 Old Generation : stop-the-world full heap collector
```
are replaced with four. They and the memory pools they affect are
```
G1 Young : incremental pure young generation collector
G1 Eden Space
G1 Survivor Space
G1 Humongous Space
G1 Free Space
G1 Mixed : incremental young + partially old collector
G1 Eden Space
G1 Survivor Space
G1 Humongous Space
G1 Old Space
G1 Free Space
G1 Full : stop-the-world full heap collector
G1 Eden Space
G1 Survivor Space
G1 Humongous Space
G1 Old Space
G1 Archive Space
G1 Free Space
G1 Concurrent Cycle : a concurrent cycle
G1 Humongous Space
G1 Old Space
G1 Free Space
```
The CollectionTime attribute for the G1 Concurrent Cycle collector is the total of a concurrent cycle's stop-the-world wall clock time. An associated young collection is reported as a separate event.
Because the G1 Archive Space is logically part of the G1 Old Space, it is associated with the G1 Full GarbageCollector, but will never be collected.
----------
JFR currently identifies three garbage collectors, New, Old, and Full. These correspond to the G1 Young, G1 Mixed, and G1 Full collectors, respectively. There are no changes to JFR event definitions.
Specification
-------------
No JMX specification change is necessary, since the per-JVM ManagementFactory and per-collector GarbageCollector MXBeans MemoryPools are undefined by the specification.