> ## Summary > > This PR proposes to introduce a pooled confined arena as an optimization for > `Arena.ofConfined()`, where small native allocations can be served from a > reusable per-thread/per-slot memory pool instead of calling the regular > native allocator for every short-lived arena. The arena remains confined to > its owner thread and is still closed normally, but its backing storage can be > reset and reused when the arena closes. The feature requires no API changes. > > ### Outline > > Platform threads: There are up to four lazily allocated pools per Thread, > encoded in `Thread.confinedMemoryPool`. > Virtual threads: fixed shared native pool with CAS-protected slots, because > per-virtual-thread native pools would not scale. > > Pooled memory is zeroed out upon _closing_ an Arena to minimize data > visibility between reuse. This means the data is visible only within a TWR > block, and never outside it. > > By default, a confined arena has access to four pools, each of size 64 bytes. > The pool sizes are configurable via a system property and can be 8, 16, 32, > or 64 bytes. Pooling can also be turned off completely by setting the pool > power-of-two size to zero. As there can be up to four pools per thread, > nested confined arenas are supported (i.e., up to four nested arenas). > > ## Static Analysis > > An extensive static corpus analysis of third-party libraries and the JDK > itself has been conducted with respect to `Area.ofConfined()` usage, > revealing that confined arenas were used _only_ in TWR blocks and _never_ in > an unstructured way. The static analysis further revealed that in most cases, > only a small amount of native memory was ever allocated, usually less than 32 > bytes, and in many cases, 8 bytes or less. This usage pattern lends itself > well to pooling. > > ## Dynamic Analysis > > A dynamic statistical analysis of actual runs was also made, where various > properties of confined arenas were recorded and summarized during a complete > tier1 test run. While a tier1 run is not necessarily representative of a > typical application workload, it provided some interesting results: > > The run produced 93 per-process histogram blocks and 788,773,092 closed > confined arenas. The result is dominated by arenas with no native allocation > at all: 375,934,768 arenas (47.661%) are in the zero-byte bucket. Counting > arenas up to 63 bytes covers 99.997% of all arena closures. > > The largest count bucket is 8-15 bytes per arena with 400,951,293 arenas > (50.832% of all arenas). The largest byte bucket is 8-15 bytes per are...
Per Minborg 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 46 additional commits since the last revision: - Refactor the solution - Merge branch 'master' into rfe-cached-arena-ofconfined-clean - Add local pools - Add 4 nested levels - Merge branch 'master' into rfe-cached-arena-ofconfined-clean - Clean up - Remove directive - Add slot config - Add comment - Simplify - ... and 36 more: https://git.openjdk.org/jdk/compare/da19de02...1e3b71b6 ------------- Changes: - all: https://git.openjdk.org/jdk/pull/31365/files - new: https://git.openjdk.org/jdk/pull/31365/files/0258a556..1e3b71b6 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=31365&range=16 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=31365&range=15-16 Stats: 256920 lines in 2839 files changed: 229861 ins; 11253 del; 15806 mod Patch: https://git.openjdk.org/jdk/pull/31365.diff Fetch: git fetch https://git.openjdk.org/jdk.git pull/31365/head:pull/31365 PR: https://git.openjdk.org/jdk/pull/31365
