Netty 提供了两种 ByteBufAllocator 的实现:PooledByteBufAllocator 和 UnpooledByteBufAllocator。

  • 前者池化了 ByteBuf 的实例以提高性能并最大限度地减少内存碎片。
  • 后者的实现不池化 ByteBuf 实例,并且在每次它被调用时都会返回一个新的实例。

Netty4.1 默认使用了 PooledByteBufAllocator。

Unpooled 缓冲区

Netty 提供了一个简单的称为 Unpooled 的工具类,它提供了静态的辅助方法来创建未池化的 ByteBuf 实例。

  • buffer() 返回一个未池化的基于堆内存存储的
  • ByteBuf directBuffer()返回一个未池化的基于直接内存存储的 ByteBuf
  • wrappedBuffer() 返回一个包装了给定数据的
  • ByteBuf copiedBuffer() 返回一个复制了给定数据的 ByteBuf

Unpooled 类还可用于 ByteBuf 同样可用于那些并不需要 Netty 的其他组件的非网络项目。

池化的最大意义在于可以重用 ByteBuf,优点有

  • 没有池化,则每次都得创建新的 ByteBuf 实例,这个操作对直接内存代价昂贵,就算是堆内存,也会增加 GC 压力
  • 有了池化,则可以重用池中 ByteBuf 实例,并且采用了与 jemalloc 类似的内存分配算法提升分配效率
  • 高并发时,池化功能更节约内存,减少内存溢出的可能

池化功能是否开启,可以通过下面的系统环境变量来设置
-Dio.netty.allocator.type={unpooled|pooled}

  • 4.1 以后,非 Android 平台默认启用池化实现,Android 平台启用非池化实现
  • 4.1 之前,池化功能还不成熟,默认是非池化实现