JDK 11 G1 Adaptive IHOP Drops to a Very Low Percent After Humongous Allocations
Applies To
Java SE JDK and JRE - Version 11 through 15
Information in this document applies to any platform.
Symptoms
The JDK 11 Initiating Heap Occupancy Percentage (IHOP) is adaptive and
set to 45%, by default. Note occupancy: ... threshold: ... (45.00) in
the following GC log entry:
[2021-03-29T17:16:38.404-0700][11271.118s][3710][debug][gc,ergo,ihop ] Request concurrent cycle initiation (occupancy higher than threshold) occupancy: 5783945216B allocation request:5861520B threshold: 3865470566B (45.00) source: concurrent humongous allocation
After some humongous allocations, IHOP suddenly drops to a very low value, resulting in back-to-back concurrent collections. In the following GC log example, IHOP drops to 0.00% and stays there for a long time, resulting in back-to-back concurrent cycle requests:
[2021-03-29T17:35:38.384-0700][12411.098s][3710][debug][gc,ergo,ihop ] Request concurrent cycle initiation (occupancy higher than threshold) occupancy: 2399141888B allocation request:5861520B threshold: 0B (0.00) source: concurrent humongous allocation
[2021-03-29T17:35:38.496-0700][12411.210s][3710][debug][gc,ergo,ihop ] Request concurrent cycle initiation (occupancy higher than threshold) occupancy: 356515840B allocation request:3748752B threshold: 0B (0.00) source: concurrent humongous allocation
[2021-03-29T17:36:08.391-0700][12441.105s][3710][debug][gc,ergo,ihop ] Request concurrent cycle initiation (occupancy higher than threshold) occupancy: 377487360B allocation request:5861520B threshold: 0B (0.00) source: concurrent humongous allocation
[2021-03-29T17:36:08.498-0700][12441.212s][3710][debug][gc,ergo,ihop ] Request concurrent cycle initiation (occupancy higher than threshold) occupancy: 348127232B allocation request:3748752B threshold: 0B (0.00) source: concurrent humongous allocation
Young GCs have collected many of those humongous objects, but the IHOP does not change from the very low value.
Cause
This issue occurs when there are many short-lived humongous objects allocated on the heap, which are collected during Young collections. The adaptive IHOP calculation, by design, does not take into account objects that are collected by Young collections, even humongous objects.
After every Young-only garbage collection, G1’s Adative IHOP calculation
is based on the old generation allocation rate
(old_gen_allocated_bytes_since_last_gc / allocation_time_in_seconds).
The value old_gen_allocated_bytes_since_last_gc consists of all
allocations into old regions, including humongous regions. However, this
does not account for the possibility that humongous objects can be
reclaimed by Young GCs. This means that humongous allocations that have
already been collected by a Young GC are still counted as allocated when
IHOP is recalculated. For applications that allocate a lot of
short-lived humongous objects, this can mean the old generation
allocation rate is erroneously inflated, which in turn, keeps the IHOP
lower than it should, resulting in back-to-back concurrent collections.
See JDK-8245511 - G1 adaptive IHOP does not account for reclamation of humongous objects by young GC for more information.
Solution
The solution is a JDK code enhancement that changes the IHOP calculation to account for reclamation of humongous objects by Young GCs. Behaviorally, this means that the IHOP may be lowered due to humongous allocations, but it will raise back up as short-lived humongous objects are reclaimed by Young GCs, thereby avoiding the multiple back-to-back concurrent collections.
This enhancement was first released in JDK 11.0.13, but it’s recommended to update to the latest JDK 11 release, which can be downloaded from Document 1414485.1 “Latest Java SE Patch Updates on MOS” or the Java Downloads page on Oracle.com. To implement the solution, please execute the following steps:
- Review the JDK 11 Consolidated Release Notes for any changes that may affect your application
- Download the JDK patch update (see links above)
- Ensure that you have made a backup of your system before applying the recommended patch update.
- Install the update in a test environment
- Confirm the following version with the command
java -version. - Retest the issue
- Migrate the solution as appropriate to other environments
Upgrading to JDK 17 or higher will also resolve this issue.
If unable to update the JDK at this time, a workaround is to disable
adaptive IHOP with the following java command line flag:
-XX:-G1UseAdaptiveIHOP Last reviewed on Sat Feb 01 2025 00:00:00 GMT+0000 (Coordinated Universal Time)