RFR: 8347335: ZGC: Use limitless mark stack memory [v2]
Axel Boldt-Christmas
aboldtch at openjdk.org
Thu Feb 20 09:04:53 UTC 2025
On Thu, 20 Feb 2025 08:09:06 GMT, Erik Österlund <eosterlund at openjdk.org> wrote:
>> When ZGC performs marking, a lock-free data structure is used to keep track of objects that still need to be traced in the object traversal. This lock-free data structure uses versioned pointer as a technique to avoid ABA problems, prevalent when writing lock-free data structures. This required partitioning pointers in the structure to embed both a version and a location.
>>
>> Due to the reduced addressability of locations with only a portion of the pointer bits, a special memory space was created to manage the data structure such that offsets could be encoded, instead of addresses.
>>
>> Since the memory area needs to be contiguous, the JVM needs to know what the expected maximum size of this space will ever be, within some limiting bounds. That is what `-XX:ZMarkStackSpaceLimit` controls.
>>
>> While this strategy has worked well in practice, the design does limit the scalability of ZGC, due to limits in how much contiguous memory can be encoded with a subset of the pointer bits. Not to mention that users have no idea what number to put in to this JVM option.
>>
>> The `-XX:ZMarkStackSpaceLimit` JVM option is needed due to using a contiguous allocator to solve an ABA problem in a lock-free data structure. By selecting another solution for the ABA problem, the need for the special contiguous memory allocator and hence the JVM option can be removed.
>>
>> This PR proposes a new solution for that original ABA problem in the lock-free data structure, which renders the entire machinery behind the `-XX:ZMarkStackSpaceLimit` JVM option redundant. The proposed technique is to use hazard pointers instead.
>>
>> The use of hazard pointers is a well established safe memory reclamation (SMR) technique for writing lock-free data structures, that we also use in the Threads list. The main idea is to publish what pointer has been read with a hazard pointer, so that concurrent threads know not to free memory that is being concurrently used. Freeing of such racingly accessed memory is deferred until it is safe, hence solving the ABA problem. This also allows using plain malloc/free instead of a custom contiguous memory allocator for these structures.
>>
>> Only popping nodes from the mark stacks requires hazard pointers, and only GC workers pop entries from the mark stacks. Therefore, hazard pointers may be stored in a per-worker variable.
>>
>> I have measured throughput, latency, marking times and memory usage across a number of programs and platforms, and not seen any inter...
>
> Erik Österlund has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains five additional commits since the last revision:
>
> - Preexisting: Missing Include
> - Spelling and const
> - Use ZAttachedArray
> - Merge branch 'master' into zgc_hazard_mark_stack
> - 8347335: ZGC: Use limitless mark stack memory
As the old saying goes `malloc's the limit`. Or maybe it was the sky.
lgtm. Good work!
-------------
Marked as reviewed by aboldtch (Reviewer).
PR Review: https://git.openjdk.org/jdk/pull/23571#pullrequestreview-2629139541
More information about the hotspot-dev
mailing list