Package io.netty.buffer
Abstraction of a byte buffer - the fundamental data structure
to represent a low-level binary and text message.
Netty uses its own buffer API instead of NIO
ByteBuffer
to
represent a sequence of bytes. This approach has significant advantage over
using ByteBuffer
. Netty's new buffer type,
ByteBuf
, has been designed from ground
up to address the problems of ByteBuffer
and to meet the
daily needs of network application developers. To list a few cool features:
- You can define your buffer type if necessary.
- Transparent zero copy is achieved by built-in composite buffer type.
- A dynamic buffer type is provided out-of-the-box, whose capacity is
expanded on demand, just like
StringBuffer
. - There's no need to call the
flip()
method anymore. - It is often faster than
ByteBuffer
.
Extensibility
ByteBuf
has rich set of operations
optimized for rapid protocol implementation. For example,
ByteBuf
provides various operations
for accessing unsigned values and strings and searching for certain byte
sequence in a buffer. You can also extend or wrap existing buffer type
to add convenient accessors. The custom buffer type still implements
ByteBuf
interface rather than
introducing an incompatible type.
Transparent Zero Copy
To lift up the performance of a network application to the extreme, you need to reduce the number of memory copy operation. You might have a set of buffers that could be sliced and combined to compose a whole message. Netty provides a composite buffer which allows you to create a new buffer from the arbitrary number of existing buffers with no memory copy. For example, a message could be composed of two parts; header and body. In a modularized application, the two parts could be produced by different modules and assembled later when the message is sent out.+--------+----------+ | header | body | +--------+----------+If
ByteBuffer
were used, you would have to create a new big
buffer and copy the two parts into the new buffer. Alternatively, you can
perform a gathering write operation in NIO, but it restricts you to represent
the composite of buffers as an array of ByteBuffer
s rather
than a single buffer, breaking the abstraction and introducing complicated
state management. Moreover, it's of no use if you are not going to read or
write from an NIO channel.
// The composite type is incompatible with the component type. ByteBuffer[] message = new ByteBuffer[] { header, body };By contrast,
ByteBuf
does not have such
caveats because it is fully extensible and has a built-in composite buffer
type.
// The composite type is compatible with the component type.ByteBuf
message =Unpooled
.wrappedBuffer(header, body); // Therefore, you can even create a composite by mixing a composite and an // ordinary buffer.ByteBuf
messageWithFooter =Unpooled
.wrappedBuffer(message, footer); // Because the composite is still aByteBuf
, you can access its content // easily, and the accessor method will behave just like it's a single buffer // even if the region you want to access spans over multiple components. The // unsigned integer being read here is located across body and footer. messageWithFooter.getUnsignedInt( messageWithFooter.readableBytes() - footer.readableBytes() - 1);
Automatic Capacity Extension
Many protocols define variable length messages, which means there's no way to determine the length of a message until you construct the message or it is difficult and inconvenient to calculate the length precisely. It is just like when you build aString
. You often estimate the length
of the resulting string and let StringBuffer
expand itself
on demand.
// A new dynamic buffer is created. Internally, the actual buffer is created // lazily to avoid potentially wasted memory space.ByteBuf
b =Unpooled
.buffer(4); // When the first write attempt is made, the internal buffer is created with // the specified initial capacity (4). b.writeByte('1'); b.writeByte('2'); b.writeByte('3'); b.writeByte('4'); // When the number of written bytes exceeds the initial capacity (4), the // internal buffer is reallocated automatically with a larger capacity. b.writeByte('5');
Better Performance
Most frequently used buffer implementation ofByteBuf
is a very thin wrapper of a
byte array (i.e. byte[]
). Unlike ByteBuffer
, it has
no complicated boundary check and index compensation, and therefore it is
easier for a JVM to optimize the buffer access. More complicated buffer
implementation is used only for sliced or composite buffers, and it performs
as well as ByteBuffer
.-
Interface Summary Interface Description ByteBufAllocator Implementations are responsible to allocate buffers.ByteBufAllocatorMetric ByteBufAllocatorMetricProvider ByteBufConvertible An interface that can be implemented by any object that know how to turn itself into aByteBuf
.ByteBufHolder A packet which is send or receive.ByteBufProcessor Deprecated. UseByteProcessor
.PoolArenaMetric Expose metrics for an arena.PoolChunkListMetric Metrics for a list of chunks.PoolChunkMetric Metrics for a chunk.PoolSubpageMetric Metrics for a sub-page.SizeClassesMetric Expose metrics for an SizeClasses. -
Class Summary Class Description AbstractByteBuf A skeletal implementation of a buffer.AbstractByteBufAllocator SkeletalByteBufAllocator
implementation to extend.AbstractDerivedByteBuf Deprecated. Do not use.AbstractReferenceCountedByteBuf Abstract base class forByteBuf
implementations that count references.AdaptiveByteBufAllocator An auto-tuning poolingByteBufAllocator
, that follows an anti-generational hypothesis.ByteBuf A random and sequential accessible sequence of zero or more bytes (octets).ByteBufInputStream AnInputStream
which reads data from aByteBuf
.ByteBufOutputStream AnOutputStream
which writes data to aByteBuf
.ByteBufUtil A collection of utility methods that is related with handlingByteBuf
, such as the generation of hex dump and swapping an integer's byte order.CompositeByteBuf A virtual buffer which shows multiple buffers as a single merged buffer.DefaultByteBufHolder Default implementation of aByteBufHolder
that holds it's data in aByteBuf
.DuplicatedByteBuf Deprecated. Do not use.EmptyByteBuf An emptyByteBuf
whose capacity and maximum capacity are all0
.PooledByteBufAllocator PooledByteBufAllocatorMetric Exposed metric forPooledByteBufAllocator
.ReadOnlyByteBuf Deprecated. Do not use.SlicedByteBuf Deprecated. Do not use.SwappedByteBuf Deprecated. use the Little Endian accessors, e.g.Unpooled Creates a newByteBuf
by allocating new space or by wrapping or copying existing byte arrays, byte buffers and a string.UnpooledByteBufAllocator SimplisticByteBufAllocator
implementation that does not pool anything.UnpooledDirectByteBuf A NIOByteBuffer
based buffer.UnpooledHeapByteBuf Big endian Java heap buffer implementation.UnpooledUnsafeDirectByteBuf A NIOByteBuffer
based buffer.UnpooledUnsafeHeapByteBuf Big endian Java heap buffer implementation.WrappedByteBuf Wraps anotherByteBuf
.