Description
Netty 4's ByteBuf
allowed for direct, unrestricted access of the underlying ByteBuffer
(s) through the nioBuffers
method. This allowed for integration with ByteBuffer
-based APIs (including java.nio), but also opened the door for memory leaks. Spring 5 exposed nioBuffer
through DataBuffer::asByteBuffer
.
Netty 5's Buffer
does not allow unrestricted access to the underlying ByteBuffer
. As a consequence, in Spring 6 DataBuffer::toByteBuffer
was introduced. This method makes a copy, and is implemented in Netty5DataBuffer::toByteBuffer
using Buffer::copyInto
.
In various places throughout Spring Framework 6, including frequently invoked code such as codecs and transports, DataBuffer::toByteBuffer
is used to integrate with ByteBuffer
-based APIs. This means that buffers are copied more frequently than in Spring 5, even in other server environments than Netty. See #29889.
Netty 5's Buffer
does allow restricted access to the underlying ByteBuffer
, through Buffer::forEachComponent
. Memory leaks are negated by only allowing access to the raw memory for the scope of the returned iterator, like so:
try (var iteration = buffer.forEachReadable()) {
for (var c = iteration.first(); c != null; c = c.next()) {
ByteBuffer componentBuffer = c.readableBuffer();
// ...
}
}
We should expose Netty 5's Buffer::forEachComponent
through a method in DataBuffer
, implement that method in Netty 4 using ByteBuf::nioBuffers
, and write an implementations for DefaultDataBuffer
.