RFR: 8357959: (bf) ByteBuffer.allocateDirect initialization can result in large TTSP spikes [v5]

Aleksey Shipilev shade at openjdk.org
Mon Jun 2 14:58:56 UTC 2025


On Thu, 29 May 2025 14:29:43 GMT, Rohitash Kumar <duke at openjdk.org> wrote:

>> ByteBuffer.allocateDirect uses UNSAFE.setMemory, causing high time-to-safepoint (100+ ms) for large (100 MB+) allocations.
>> 
>> This PR applies a simple fix by chunking the zeroing operation within ByteBuffers. A more robust solution would be to add chunking inside UNSAFE.setMemory itself. However Its not that straightforward as mentioned by Aleksey in [JDK-8357959](https://bugs.openjdk.org/browse/JDK-8357959)
>>>Looks like all current uses we care about are in Buffers. Taking a safepoint within cleaning would open some questions whether any VM code expect to see semi-initialized area we are busy cleaning up. For Buffers, this question does not arise. Therefore, we can do the fix in Buffers first, without changing the Unsafe itself.
>>  
>> I can pursue that if its preferred. I chose 1 MB as a chunk size some what arbitrarily I am open to suggestion, if there are better options.
>> 
>> For verification, I tested the fix against the reproducer - [gist](https://gist.github.com/rk-kmr/be4322b72a14ae04aeefc0260c01acf6) and confirmed that ttsp timing were lower.
>> 
>> **before**
>> 
>> 0.444s][info][safepoint,stats] ThreadDump                   [             13               1 ][        194156625      65291  194221916 ]               0
>> [0.662s][info][safepoint,stats] ThreadDump                   [             13               1 ][        200013875      87834  200101709 ]               0
>> [0.858s][info][safepoint,stats] ThreadDump                   [             13               1 ][        183762583      43417  183806000 ]               0
>> [1
>> 
>> **after**
>> 
>> 1.705s][info][safepoint,stats] ThreadDump                   [             11               1 ][            92792      24958     117750 ]               0
>> [1.724s][info][safepoint,stats] ThreadDump                   [             11               1 ][           497375      94041     591416 ]               0
>> [1.736s][info][safepoint,stats] ThreadDump                   [             11               1 ][           156750      47208     203958 ]               0
>> [1.747s][info][safepoint,stats] ThreadDump                   [             11               1 ][           121958      28334     150292 ]               0
>> 
>> 
>> I added a benchmark to ensure that chunking doesn't introduce significant overhead across different allocation sizes, and following results confirm that. 
>> 
>> **Before**
>> 
>> Benchmark                                              (bytes)  Mode  Cnt          Score         Error  Units
>> B...
>
> Rohitash Kumar has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Remove redundant comment

Looks good to me, but we need to polish the benchmark.

test/micro/org/openjdk/bench/java/nio/ByteBufferAllocationBenchmark.java line 43:

> 41: @State(Scope.Thread)
> 42: @Measurement(iterations = 5)
> 43: @Warmup(iterations = 5)

Suggestion:

@Warmup(iterations = 3, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 3, time = 1, timeUnit = TimeUnit.SECONDS)
@Fork(3)

test/micro/org/openjdk/bench/java/nio/ByteBufferAllocationBenchmark.java line 44:

> 42: @Measurement(iterations = 5)
> 43: @Warmup(iterations = 5)
> 44: public class ByteBufferAllocationBenchmark {

I could have sworn we added some `ByteBuffer` allocation benchmarks before. But I cannot find them. For consistency with other tests, I suggest naming this test `DirectByteBufferAlloc.java`.

test/micro/org/openjdk/bench/java/nio/ByteBufferAllocationBenchmark.java line 50:

> 48:             "1024", // 1KB
> 49:             "1048576", // 1 MB
> 50:             "2147483647" // ~2 GB

Trying to allocate 2GB would likely fail on lots of testing hosts. Since we want to tickle 1MB limit, I suggest testing with 16MB.

-------------

PR Review: https://git.openjdk.org/jdk/pull/25487#pullrequestreview-2888804487
PR Review Comment: https://git.openjdk.org/jdk/pull/25487#discussion_r2121408158
PR Review Comment: https://git.openjdk.org/jdk/pull/25487#discussion_r2121405948
PR Review Comment: https://git.openjdk.org/jdk/pull/25487#discussion_r2121409454


More information about the nio-dev mailing list