Skip to content

Auto-port 5.0: Fix IllegalReferenceCountException in AdaptiveByteBuf.deallocate()#16673

Merged
chrisvest merged 1 commit into
5.0from
auto-port-pr-16654-to-5.0
Apr 21, 2026
Merged

Auto-port 5.0: Fix IllegalReferenceCountException in AdaptiveByteBuf.deallocate()#16673
chrisvest merged 1 commit into
5.0from
auto-port-pr-16654-to-5.0

Conversation

@netty-project-bot

Copy link
Copy Markdown
Contributor

Auto-port of #16654 to 5.0
Cherry-picked commit: 66568d1


Motivation:

Fix IllegalReferenceCountException in AdaptiveByteBuf.deallocate() when JFR enabled when lot's of buffer is used, we noticed this error:

io.netty.util.IllegalReferenceCountException
    at AdaptiveByteBuf.rootParent(AdaptivePoolingAllocator.java:1653)
    at AdaptiveByteBuf.isDirect(AdaptivePoolingAllocator.java:1725)
    at AbstractBufferEvent.fill(AbstractBufferEvent.java:44)
    at AdaptiveByteBuf.deallocate(AdaptivePoolingAllocator.java:2110)
    at AbstractReferenceCountedByteBuf.handleRelease(AbstractReferenceCountedByteBuf.java:93)
    at AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:83)
    at AdaptivePoolingAllocator$MagazineGroup.allocate(AdaptivePoolingAllocator.java:431)
    at AdaptivePoolingAllocator.allocate(AdaptivePoolingAllocator.java:271)
    at AdaptiveByteBufAllocator.newDirectBuffer(AdaptiveByteBufAllocator.java:67)

Modification:

When MagazineGroup.allocate() exhausts all magazine stripes under high
contention, the bail-out path calls buf.release() on an AdaptiveByteBuf
that was obtained from newBuffer() but never initialised via init().
The buffer's rootParent field is therefore null.

With JFR recording active, deallocate() fires a FreeBufferEvent before
clearing rootParent. AbstractBufferEvent.fill() calls buf.isDirect()
which delegates to rootParent().isDirect(), and rootParent() throws
IllegalReferenceCountException when the field is null.

Result:

JFR events are emitted even under pressure

…16654)

Motivation:

Fix IllegalReferenceCountException in AdaptiveByteBuf.deallocate() when
JFR enabled when lot's of buffer is used, we noticed this error:

```
io.netty.util.IllegalReferenceCountException
    at AdaptiveByteBuf.rootParent(AdaptivePoolingAllocator.java:1653)
    at AdaptiveByteBuf.isDirect(AdaptivePoolingAllocator.java:1725)
    at AbstractBufferEvent.fill(AbstractBufferEvent.java:44)
    at AdaptiveByteBuf.deallocate(AdaptivePoolingAllocator.java:2110)
    at AbstractReferenceCountedByteBuf.handleRelease(AbstractReferenceCountedByteBuf.java:93)
    at AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:83)
    at AdaptivePoolingAllocator$MagazineGroup.allocate(AdaptivePoolingAllocator.java:431)
    at AdaptivePoolingAllocator.allocate(AdaptivePoolingAllocator.java:271)
    at AdaptiveByteBufAllocator.newDirectBuffer(AdaptiveByteBufAllocator.java:67)

```
Modification:

When MagazineGroup.allocate() exhausts all magazine stripes under high
contention, the bail-out path calls buf.release() on an AdaptiveByteBuf
    that was obtained from newBuffer() but never initialised via init().
    The buffer's rootParent field is therefore null.

With JFR recording active, deallocate() fires a FreeBufferEvent before
    clearing rootParent. AbstractBufferEvent.fill() calls buf.isDirect()
    which delegates to rootParent().isDirect(), and rootParent() throws
    IllegalReferenceCountException when the field is null.

Result:

JFR events are emitted even under pressure

(cherry picked from commit 66568d1)
@chrisvest chrisvest added this to the 5.0.0.Final milestone Apr 21, 2026
@chrisvest chrisvest merged commit 0e1bf16 into 5.0 Apr 21, 2026
11 of 13 checks passed
@chrisvest chrisvest deleted the auto-port-pr-16654-to-5.0 branch April 21, 2026 00:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants