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 之前,池化功能还不成熟,默认是非池化实现