Skip to content

Conversation

@jsikstro
Copy link
Member

@jsikstro jsikstro commented Oct 22, 2025

Hello,

Parallel's MutableNUMASpace is the only GC interface that uses the Thread parameter passed through the general CollectedHeap interface to tlab_capacity, tlab_used, and unsafe_max_tlab_alloc. It would be nice if Parallel's MutableNUMASpace could do without the Thread and instead find a thread-agnostic approach. By removing the need for the thread, it becomes possible to clean up the shared CollectedHeap interface, which makes it easier to read and maintain all GCs. Also, the lgrp_id that is stored in the Thread class should really have been moved to GCThreadLocalData after that concept was created, but with a thread-agnostic approach, the field can be removed entirely.

The current solution is not without problems. When a new allocation is made inside one of the LGRP spaces in MutableNUMASpace using cas_allocate(), the NUMA/LGRP id is polled and stored inside the Thread, and we only attempt to allocate on that LGRP. If allocation fails on the local LGRP, we do not try to allocate on any other (remote) LGRP(s). This fact is reflected in the TLAB accounting methods tlab_capacity, tlab_used, and unsafe_max_tlab_alloc, which only check how much memory is used, etc., for the LGRP matching the stored LGRP id in the Thread. This model breaks down when threads are allowed to migrate between different CPUs, and therefore also NUMA nodes, which might change the LGRP id.

For example, a system with two NUMA nodes gives us two LGRPs with ids 0 and 1. If a thread allocates most of its memory on LGRP 0 and then migrates to a CPU on LGRP 1, the thread will show that it allocated a significant amount of memory, but the used memory on the LGRP it is currently on could be very low. This would give a disproportionate allocation fraction. This is not a problem as the TLAB code accounts for this, but for a different reason entirely. The other way around could also be problematic. If a thread allocates very little memory on LGRP 0 and then migrates to LGRP 1, where another thread has allocated a lot of memory, the allocation fraction will be very low, when it could have a really high fraction if accounting for the used memory on its original LGRP.

A solution to both of these issues is to average the capacity, used, and available memory across all LGRPs for the TLAB accounting methods. This approach provides a more accurate and stable view of memory usage and availability, regardless of thread migration or imbalances in NUMA/LGRP allocation. However, there are trade-offs to consider. Averaging the accounting may mask allocation pressure on specific LGRPs and could result in the allocation history of TLABs being updated more/less frequently. In summary, considering the whole eden space (i.e., the entire MutableNUMASpace) instead of just a single LGRP when accounting for TLABs should give a more holistic view.

I plan to clean up the Thread* parameter to tlab_capacity, tlab_used and unsafe_max_tlab_alloc in a following RFE. Since it is a pretty significant cleanup

Testing:

  • No performance impact on traditional benchmarks running with -XX:+UseParallelGC -XX:+UseNUMA. Slight improvement on SPECjbb2005.
  • hotspot:tier1-4 on a local NUMA machine

Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Issue

  • JDK-8370345: Parallel: Rework TLAB accounting in MutableNUMASpace (Enhancement - P4)

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/27935/head:pull/27935
$ git checkout pull/27935

Update a local copy of the PR:
$ git checkout pull/27935
$ git pull https://git.openjdk.org/jdk.git pull/27935/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 27935

View PR using the GUI difftool:
$ git pr show -t 27935

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/27935.diff

Using Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Oct 22, 2025

👋 Welcome back jsikstro! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented Oct 22, 2025

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

@openjdk openjdk bot added the hotspot hotspot-dev@openjdk.org label Oct 22, 2025
@openjdk
Copy link

openjdk bot commented Oct 22, 2025

@jsikstro The following label will be automatically applied to this pull request:

  • hotspot

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the rfr Pull request is ready for review label Oct 22, 2025
@mlbridge
Copy link

mlbridge bot commented Oct 22, 2025

Webrevs

@jsikstro
Copy link
Member Author

/cc add hotspot-gc

@openjdk openjdk bot added the hotspot-gc hotspot-gc-dev@openjdk.org label Oct 22, 2025
@openjdk
Copy link

openjdk bot commented Oct 22, 2025

@jsikstro
The hotspot-gc label was successfully added.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hotspot hotspot-dev@openjdk.org hotspot-gc hotspot-gc-dev@openjdk.org rfr Pull request is ready for review

Development

Successfully merging this pull request may close these issues.

1 participant