RFR: 8361099: Shenandoah: Improve heap lock contention by using CAS for memory allocation [v20]
Xiaolong Peng
xpeng at openjdk.org
Tue Jan 13 22:56:00 UTC 2026
On Wed, 7 Jan 2026 14:56:15 GMT, Kelvin Nilsen <kdnilsen at openjdk.org> wrote:
>> src/hotspot/share/gc/shenandoah/shenandoahAllocator.cpp line 114:
>>
>>> 112: HeapWord* obj = attempt_allocation_in_alloc_regions(req, in_new_region, alloc_start_index(), dummy);
>>> 113: if (obj != nullptr) {
>>> 114: return obj;
>>
>> Even in the case that we successfully fill our allocation request, if regions_ready_for_refresh is greater than some percentage of _alloc_region_count (e.g. > _alloc_region_count / 4), then we should grab the heap lock and refresh_alloc_regions() here. Otherwise, we will gradually degrade the number of directly_allocatable_regions until we are down to one before we refresh any of them.
>
> After further thought, am thinking the threshold for refresh_alloc_regions() might be if (regions_ready_for_refresh >= _alloc_region_count / 2). That would reduce the number of slow paths through the allocator. If we can re-randomize the thread-local start indexes when their original start index hits a retire-able region, this might work ok.
I have added support for this, it works as:
obj = fast-path-alloc();
if (obj != nullptr && regions_ready_for_refresh < _alloc_region_count / 2) {
return obj;
}
if (obj = nullptr) {
obj = slow-path-alloc();
} else {
ShenandoahHeapLocker locker(ShenandoahHeap::heap()->lock(), false);
refresh_alloc_regions();
}
If fast-path-alloc succeeds but determines that there are more than 50% of alloc regions are ready for retiring, when it take heap heap lock to refresh alloc regions, it CANNOT yield to safepoint, because the thread is holding uninitialized obj.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/26171#discussion_r2688380076
More information about the shenandoah-dev
mailing list