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