回答
Netty 精心设计和实现的内存模型是 Netty 高性能的核心原因之一。Netty 的内存模型核心围绕 ByteBuf
、ByteBufAllocator
、零拷贝、以及基于 jemelloc
实现的内存分配算法来展开的。
ByteBuf
:Netty 引入ByteBuf
来作为在网络中传输数据的载体,取代 Java NIO 的ByteBuffer
。相比 ByteBuffer ,ByteBuf
通过读写索引分离来提供更加高效的操作,通过引用计数机制和池化技术来提高内存使用效率。ByteBufAllocator
:负责ByteBuf
的内存分配,包括池化和非池化两种分配器,其中池化分配器通过预分配和重用内存块来减少内存分配的开销,并通过内存分割和子分配策略来优化内存管理,减少碎片。- 零拷贝:Netty 利用
ByteBuf
的CompositeByteBuf
和slice()
来实现零拷贝技术。 - 基于
jemelloc
的内存分配算法:
扩展
关于 ByteBuf
和 零拷贝请阅读下面三篇文章:
下面大明哥详细介绍 Netty 基于 jemelloc
的内存分配算法。
Netty 基于jemelloc 的内存分配算法
网上绝大多数文章都是分析
jemelloc 3
的内存分配算法,但是 Netty 从 4.1.45 版本开始,就基于jemalloc4.x
算法对内存模块进行了重构,而且两者差别比较大。这里,大明哥就介绍jemalloc4
。同时,Netty 的内存分配是非常复杂,不是一篇文章能够说清楚的,所以这里就只做整体介绍,具体细节需要各位大佬自行去研究了。
内存规格
我们知道基于 jemalloc3 的 Netty将整个内存划分为:Tiny、Small、Normal 和 Huge 四类。其中 Tiny 为 0 ~ 512 B 之间的内存块,Small 为 512B ~ 8KB 之间的内存块,Normal 为 8KB ~ 16M 之间的内存块,Huge 则是大于 16M 的,如下图:
而基于 jemalloc4 的 Netty 则将 Tiny 去掉了,保留了 Small、Normal、Huge,内存划分如下:
- Small:[0-28K]
- Normal:(28K - 16M]
- Huge:> 16M
整体架构
下图是基于 jemalloc3 的 Netty 的内存池架构图: