如何在我们的程序中获得 ByteBuf 的实例,并使用它呢?Netty 提供了两种方式

ByteBufAllocator 接口

Netty 通过 interface ByteBufAllocator 分配我们所描述过的任意类型的 ByteBuf 实例。
可以通过 Channel(每个都可以有一个不同的 ByteBufAllocator 实例)或者绑定到 ChannelHandler 的 ChannelHandlerContext 获取一个到 ByteBufAllocator 的引用。

buffer() 返回一个基于堆或者直接内存存储的 ByteBuf (默认池化,直接内存 )
heapBuffer() 返回一个基于堆内存存储的 ByteBuf
directBuffer() 返回一个基于直接内存存储的 ByteBuf
compositeBuffer() 返回一个可以通过添加最大到指定数目的基于堆的或者直接 内存存储的缓冲区来扩展的 CompositeByteBuf
ioBuffer() 返回一个用于套接字的 I/O 操作的 ByteBuf,当所运行的环境具有 sun.misc.Unsafe 支持时,返回基于直接内存存储的 ByteBuf, 否则返回基于堆内存存储的 ByteBuf;当指定使用 PreferHeapByteBufAllocator 时,则只会返回基于堆内存存储的 ByteBuf。

直接内存 vs 堆内存

  • 可以使用下面的代码来创建池化基于堆的 ByteBuf

ByteBuf buffer = ByteBufAllocator.DEFAULT.heapBuffer(10);

  • 也可以使用下面的代码来创建池化基于直接内存的 ByteBuf

ByteBuf buffer = ByteBufAllocator.DEFAULT.directBuffer(10);

  • 直接内存创建和销毁的代价昂贵,但读写性能高(少一次内存复制),适合配合池化功能一起用
  • 直接内存对 GC 压力小,因为这部分内存不受 JVM 垃圾回收的管理,但也要注意及时主动释放