JDK-8273941 : G1 GC tuning guide updates for JDK18
  • Type: Bug
  • Component: docs
  • Sub-Component: guides
  • Affected Version: 18
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2021-09-17
  • Updated: 2022-03-14
  • Resolved: 2022-03-14
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 18
18.0.1Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
With JDK-8017163 there were significant changes to not only how the remembered set is represented, but also output the garbage collector provides.

The GC tuning guide (linking the one for 17: https://docs.oracle.com/en/java/javase/17/gctuning/garbage-first-garbage-collector-tuning.html#GUID-A0343B53-A690-4DDE-98F9-9877096DBF0F) the section "High Update RS and Scan RS Times" needs to be revised.

Requested changes are added as comments starting with the "change:" keyword.
Comments
Everything seems good. I resolved this issue - I hope this is the correct way to carry documentation issues along the process.
14-03-2022

Hi Thomas, I have incorporated the suggested changes. Request you to review and confirm if the changes looks OK. Here is the link to html: https://docs-uat.us.oracle.com/en/java/javase/18/gctuning/index.html
10-03-2022

change: in section "Garbage Collector, Heap, and Runtime Compiler Default Selections" (https://docs.oracle.com/en/java/javase/17/gctuning/ergonomics.html#GUID-DA88B6A6-AF89-4423-95A6-BBCBD9FAE781), at the end of the list: add the note: Note: The VM considers machines as server-class if the VM detects more than two processors and a heap size larger or equal to 1792 MB.
03-03-2022

change: in section "Garbage Collector, Heap, and Runtime Compiler Default Selections" (https://docs.oracle.com/en/java/javase/17/gctuning/ergonomics.html#GUID-DA88B6A6-AF89-4423-95A6-BBCBD9FAE781), replace the item * Garbage-First (G1) Collector with * Garbage-First (G1) Collector on server-class machines, Serial Collector otherwise.
03-03-2022

change: in section "High Update RS and Scan RS Times" (https://docs.oracle.com/en/java/javase/17/gctuning/garbage-first-garbage-collector-tuning.html#GUID-A0343B53-A690-4DDE-98F9-9877096DBF0F) replace the whole subsection with: High Merge Heap Roots and Scan Heap Roots Times One way to reduce these phases is to decrease the number of remembered set entries in the combined remembered sets. Adjusting the size of the heap regions by using the option -XX:G1HeapRegionSize decreases the number of cross-region references size of the remembered set. Larger regions tend to have fewer cross-region references, so the relative amount of work spent in processing them decreases, although at the same time, larger regions may mean more live objects to evacuate per region, increasing the time for other phases. If a significant amount of time of the garbage collection, i.e. more than 60%, is spent in these two phases, one option could be decreasing the granularity of the remembered set entries by decreasing the value of the -XX:GCCardSizeInBytes option: higher granularity decreases the amount of work to find references, at the cost of some additional memory. See the "Remembered Set" section for more information about the tradeoff. Spurious high Scan Heap Roots times in combination with the application allocating large objects may be caused by an optimization that tries to reduce concurrent remembered set updates work by batching it. If the application that created such a batch happens just before a garbage collection, this might have a negative impact on Merge Heap Roots time. Use -XX:-ReduceInitialCardMarks to disable this optimization and potentially avoid this situation.
02-03-2022

change: in section "Garbage Collection Pauses and Collection Set" (https://docs.oracle.com/en/java/javase/17/gctuning/garbage-first-g1-garbage-collector1.html#GUID-3A99AE6C-F80A-4565-A27C-B4AEDF5CDF71), at the end of the section add the following paragraphs (including a sub-heading) Remembered Set To evacuate the collection set G1 manages a remembered set: the set of locations outside the collection set that contain references into the collection set. When an object from the collection set moves during garbage collection, any other references to that object from outside the collection set need to be changed to point to the new location of the object. The remembered set entries represent approximate locations to save memory: often references close together reference objects close together. G1 logically partitions the heap into cards, by default 512 byte sized areas. Remembered set entries are compressed indexes of these cards. For recovering the original references, G1 maintains two tables representing state of these cards, each taking up 1/card size percent of the Java heap. G1 initially manages this remembered set on a per-region basis: every region contains a per-region remembered set, the set of locations with potential references into this region. During garbage collection, the remembered set for the entire collection set is generated from these. The remembered sets are created mostly lazily: between the Remark and Cleanup pause G1 rebuilds the remembered set of all collection set candidate regions. Other than that G1 always maintains remembered sets for young generation region as they are collected at every collection and by default some humongous objects for eager reclaim. Garbage Collection Process A garbage collection consists of four phases. * the "Pre Evacuate Collection Set" phase performs some preparatory work for garbage collection: disconnecting TLABs from mutator threads, selecting the collection set for this collection as described in Section 7-4 "Java Heap Sizing" section and other small preparatory work. * during "Merge Heap Roots" G1 creates a single unified remembered set for later easier parallel processing from the collection set regions. This removes many duplicates from the individual remembered sets that would otherwise be needed to be filtered out later in a more expensive way. * the "Evacuate Collection Set" phase contains the bulk of the work: G1 starts moving objects starting from the roots. A root reference is a reference from outside the collection set, either from some VM internal data structure (External Roots), code (Code Roots) or from the remainder of the Java heap (Heap Roots). For all roots, G1 copies the referenced object in the collection set to its destination, processes its references into the collection set as new roots until there are no more roots. Individual timing for these phases can be observed with -Xlog:gc+phases=debug logging in the Ext Root Scanning, Code Root Scan, Scan Heap Roots and Object Copy sub-phases respectively. G1 may optionally repeat main evacuation phases for optional collection sets. * "Post Evacuate Collection Set" consists of clean-up work including reference processing and setup for the following mutator phase. These phases correspond to the phases printed with -Xlog:gc+phases=info logging.
02-03-2022

change: in section "Garbage Collection Pauses and Collection Set" (https://docs.oracle.com/en/java/javase/17/gctuning/garbage-first-g1-garbage-collector1.html#GUID-3A99AE6C-F80A-4565-A27C-B4AEDF5CDF71), before the paragraph The collection set is the set of source regions to reclaim space from. Depending on the type of garbage collection, the collection set consists of different kinds of regions: add a "Collection Set" subheading
01-03-2022

add: after section "Mixed Collections take too long" (https://docs.oracle.com/en/java/javase/17/gctuning/garbage-first-garbage-collector-tuning.html#GUID-D2B6ADCE-6766-4FF8-AA9D-B7F4F3D0F469), add the following section Collections Occur Back to Back G1 default MMU settings allow back-to-back garbage collections. The default value of -XX:GCPauseIntervalMillis is just slightly higher than -XX:MaxGCPauseMillis. In case you observe continuous back-to-back garbage collections, which results in the application not progressing, increase the value of -XX:GCPauseIntervalMillis to an acceptable value. G1 will then try to space out garbage collections more.
01-03-2022

change: in section "Mixed Collections take too long" (https://docs.oracle.com/en/java/javase/17/gctuning/garbage-first-garbage-collector-tuning.html#GUID-D2B6ADCE-6766-4FF8-AA9D-B7F4F3D0F469), replace first paragraph: Mixed collections are used to reclaim space in the old generation. The collection set of mixed collections contains young and old generation regions. You can obtain information about how much time evacuation of either young or old generation regions contribute to the pause-time by enabling the gc+ergo+cset=trace log output. Look at the predicted young region time and predicted old region time for young and old generation regions respectively. If the predicted young region time is too long, then see Young-Only Collections Within the Young-Only Phase Take Too Long for options. Otherwise, to reduce the contribution of the old generation regions to the pause-time, G1 provides three options: with Mixed young collections are used to reclaim space in the old generation. The collection set of mixed collections contains young and old generation regions. You can obtain information about how much time evacuation of either young or old generation regions contribute to the pause-time by enabling the gc+ergo+cset=debug log output. Look for the following log message: Added young regions to CSet. [...] predicted eden time: 4.86ms, predicted base time: 9.98ms, target pause time: 200.00ms, [...] Eden time and base time together give the predicted young region time, i.e. the time G1 expects evacuating the young generation will take. The log message for predicting old region time looks as follows: Finish choosing collection set old regions. [...] predicted initial time: 147.70ms, predicted optional time: 15.45ms, [...] Here, predicted initial time represents predicted old region time, i.e. the time G1 expects evacuating the minimum set of old generation regions will take. If the predicted young region time is too long, then see Young-Only Collections Within the Young-Only Phase Take Too Long for options. Otherwise, to reduce the contribution of the old generation regions to the pause-time, G1 provides three options:
01-03-2022

change: in the "Observing Full Garbage Collections" (https://docs.oracle.com/en/java/javase/17/gctuning/garbage-first-garbage-collector-tuning.html#GUID-0DD93225-0BCF-4605-B365-E9833F5BD2FC) section, replace the first paragraph: A full heap garbage collection (Full GC) is often very time consuming. Full GCs caused by too high heap occupancy in the old generation can be detected by finding the words Pause Full (Allocation Failure) in the log. Full GCs are typically preceded by garbage collections that encounter an evacuation failure indicated by to-space exhausted tags. with A full heap garbage collection (Full GC) is often very time consuming. Full GCs caused by too high heap occupancy in the old generation can be detected by finding the words *Pause Full (G1 Compaction Pause)* in the log. Full GCs are typically preceded by garbage collections that encounter an evacuation failure indicated by *Evacuation Failure* tags.
01-03-2022

change: in the "Space-Reclamation Phase Generation Sizing" (https://docs.oracle.com/en/java/javase/17/gctuning/garbage-first-g1-garbage-collector1.html#GUID-6D6B18B1-063B-48FF-99E3-5AF059C43CE8) section, replace the first paragraph: During the space-reclamation phase, G1 tries to maximize the amount of space that is reclaimed in the old generation in a single garbage collection pause. The size of the young generation is set to the minimum allowed, typically as determined by - XX:G1NewSizePercent. Replace with During the space-reclamation phase, G1 tries to maximize the amount of space that is reclaimed in the old generation in a single garbage collection pause. The size of the young generation is typically set to the minimum allowed, typically as determined by -XX:G1NewSizePercent, but also considering the MMU specification.
01-03-2022

change: in the "Young-Only Phase Generation Sizing" (https://docs.oracle.com/en/java/javase/17/gctuning/garbage-first-g1-garbage-collector1.html#GUID-C268549C-7D95-499C-9B24-A6670B44E49C) section, in the first paragraph: Replace the first paragraph G1 always sizes the young generation at the end of a normal young collection for the next mutator phase. This way, G1 can meet the pause time goals that were set using - XX:MaxGCPauseTimeMillis and -XX:PauseTimeIntervalMillis based on long-term observations of actual pause time. It takes into account how long it took young generations of similar size to evacuate. This includes information like how many objects had to be copied during collection, and how interconnected these objects had been. With G1 always sizes the young generation at the end of a normal young collection for the next mutator phase. This way, G1 can meet the pause time goals that were set using - XX:MaxGCPauseTimeMillis and -XX:GCPauseIntervalMillis based on long-term observations of actual pause time. This calculation takes into account how long it took young generations of similar size to evacuate. This includes information like how many objects had to be copied during collection, and how interconnected these objects had been. The -XX:GCPauseIntervalMillis and -XX:MaxGCPauseTimeMillis options define a minimum mutator utilization (MMU). G1 will try for every possible time range of -XX:GCPauseIntervalMillis at most use -XX:MaxGCPauseTimeMillis milliseconds for garbage collection pauses.
01-03-2022

change: in section "Determining Initiating Heap Occupancy" (https://docs.oracle.com/en/java/javase/17/gctuning/garbage-first-g1-garbage-collector1.html#GUID-572C9203-AB27-46F1-9D33-42BA4F3C6BF3), replace the first paragraph The Initiating Heap Occupancy Percent (IHOP) is the threshold at which an Initial Mark collection is triggered and it is defined as a percentage of the old generation size. with The Initiating Heap Occupancy Percent (IHOP) is the threshold at which a Concurrent Start collection is triggered and it is defined as a percentage of the old generation size.
23-02-2022

change: in section "Garbage Collection Pauses and Collection Set" (https://docs.oracle.com/en/java/javase/17/gctuning/garbage-first-g1-garbage-collector1.html#GUID-3A99AE6C-F80A-4565-A27C-B4AEDF5CDF71), the last paragraph: G1 prepares the collection set candidate regions during the concurrent cycle. During the Remark pause, G1 selects regions that have a low occupancy, which are regions that contain a significant amount of free space. These regions are then prepared concurrently between the Remark and Cleanup pauses for later collection. The Cleanup pause sorts the results of this preparation according to their efficiency. More efficient regions that seem to take less time to collect and that contain more free space are preferred in subsequent mixed collections. replace with: The collection set candidate regions are regions that are highly likely to be collected in the space reclamation phase. G1 selects them during the Remark pause according to how much live data they contain and their connectivity with other regions. Regions with little live data (lots of free space) are preferred over regions that are mostly live, and regions with little connectivity over regions with high connectivity, as the effort to collect these more "efficient" regions is smaller. G1 will drop regions that do not contribute much to free memory gain from the collection set candidate regions. This includes all regions where the amount of space that can be reclaimed is less than -XX:G1HeapWastePercent percent of the current heap size. G1 will not collect these regions later this space reclamation phase. Between the Remark and Cleanup pause G1 proceeds to prepare them for later collection, with the Cleanup pause finishing the work and sorting them according to efficiency. More efficient regions that take less time to collect and that contain more free space are preferably collected in the subsequent Mixed collections.
23-02-2022

change: in section "Space-Reclamation Phase Generation Sizing" (https://docs.oracle.com/en/java/javase/17/gctuning/garbage-first-g1-garbage-collector1.html#GUID-6D6B18B1-063B-48FF-99E3-5AF059C43CE8), replace the paragraph: The Space-Reclamation phase ends when the remaining amount of space that can be reclaimed in the collection set candidate regions is less than the percentage set by - XX:G1HeapWastePercent. with The Space-Reclamation phase ends when there are no more regions in the collection set candidate regions set.
23-02-2022

change: in section "Java Heap Sizing" (https://docs.oracle.com/en/java/javase/17/gctuning/garbage-first-g1-garbage-collector1.html#GUID-3F6AE9BA-32AF-4C36-B8C0-721EE45D17A7), replace the first paragraph: G1 respects standard rules when resizing the Java heap, using -XX:InitialHeapSize as the minimum Java heap size, -XX:MaxHeapSize as the maximum Java heap size, - XX:MinHeapFreeRatio for the minimum percentage of free memory, -XX:MaxHeapFreeRatio for determining the maximum percentage of free memory after resizing. The G1 collector considers to resize the Java heap during a the Remark and the Full GC pauses only. This process may release memory to or allocate memory from the operating system. with (keep formatting of words with "-XX:"): G1 respects standard rules when resizing the Java heap, using -XX:InitialHeapSize as the minimum Java heap size, -XX:MaxHeapSize as the maximum Java heap size, - XX:MinHeapFreeRatio for the minimum percentage of free memory, -XX:MaxHeapFreeRatio for determining the maximum percentage of free memory after resizing. The G1 collector considers to resize the Java heap according to these options during a the Remark and the Full GC pauses only. This process may release memory to or allocate memory from the operating system. Heap expansion occurs within the collection pause, while memory release occurs after the pause concurrent to the application.
23-02-2022

change: in section "Garbage Collection Cycle" (https://docs.oracle.com/en/java/javase/17/gctuning/garbage-first-g1-garbage-collector1.html#GUID-F1BE86FA-3EDC-4D4F-BDB4-4B044AD83180), in the item "Space reclamation" (item 2) below figure 7.2, Space-reclamation phase: This phase consists of multiple Mixed collections that in addition to young generation regions, also evacuate live objects of sets of old generation regions. The space-reclamation phase ends when G1 determines that evacuating more old generation regions wouldn't yield enough free space worth the effort. replace with: Space-reclamation phase: This phase consists of multiple young collections that in addition to young generation regions, also evacuate live objects of sets of old generation regions. These collections are also called Mixed collections. The space-reclamation phase ends when G1 determines that evacuating more old generation regions wouldn't yield enough free space worth the effort.
23-02-2022

change: in section "Garbage Collection Cycle" (https://docs.oracle.com/en/java/javase/17/gctuning/garbage-first-g1-garbage-collector1.html#GUID-F1BE86FA-3EDC-4D4F-BDB4-4B044AD83180), in the item "Concurrent Start" below figure 7.2, "Concurrent Start : This type of collection starts the marking process in addition to performing a Normal young collection. Concurrent marking determines all currently reachable (live) objects in the old generation regions to be kept for the following space-reclamation phase. While collection marking hasn’t completely finished, Normal young collections may occur. Marking finishes with two special stop-the-world pauses: Remark and Cleanup. " At the end, add: The Concurrent Start pause may also determine that there is no need to follow through with marking: in this case, a short concurrent mark undo phase occurs, and the Young Only phase continues. In this case no Remark and Cleanup pauses will occur.
23-02-2022

change: in the "Ergonmic Defaults for G1 GC" (https://docs.oracle.com/en/java/javase/17/gctuning/garbage-first-g1-garbage-collector1.html#GUID-082C967F-2DAC-4B59-8A81-0CEC6EEB9016) section, in Table 7-1, "Ergonomic Defaults for G1 GC", in the row with "-XX:G1HeapRegionSize=<ergo>", change the text in the second column to: The size of the heap regions. The default value is based on the maximum heap size and it is calculated to render roughly 2048 regions, with a maximum ergonomically determined value of 32 MB. A size given by the user must be a power of 2, and valid values range from 1 to 512 MB.
23-02-2022

change: in section "Behavior in Very Tight Heap Situations" (https://docs.oracle.com/en/java/javase/17/gctuning/garbage-first-g1-garbage-collector1.html#GUID-BE157AF6-29E7-461A-82CF-50C1978785DA). Between the second and third paragraph add: G1 tries to avoid evacuation failure during young collections by scheduling Preventive young collections. The assumption is that an additional regular young collection that does not incur an evacuation failure might free enough memory in the old generation by reclaiming humongous regions to not incur the overhead of such a garbage collection at all. Preventive young collections may be turned off using the -XX:-UsePreventiveGC option.
23-02-2022

Also add information about heap region size changes and configurable card size Here's some snipped comment about the card size that could be added there: In general, applications spending a significant amount of time scanning for references into evacuated areas may benefit significantly from smaller card sizes. Conversely, applications spending only a very small amount of time scanning for references may benefit from larger card sizes. E.g. for G1, with `-Xlog:gc+phases=debug` logging you can see a breakdown of the `Evacuate Collection Set` phase, looking for the `Scan Heap Roots` time. There is no such logging for Serial and Parallel GC.
19-11-2021

The guide should also make it clear the "Mixed" collections are a type of young collections. They are somewhat called out completely different than Young collections. The text mentions young-only though, but not in the context of collection names.
20-09-2021

Actually I think that the mentioned section has been out of date for quite some time.
20-09-2021