Netty ByteBuf:直接内存 vs 堆内存
Netty的ByteBuf分配和Java NIOByteBuffer类似
// 堆内存
ByteBuf heapBuf = allocator.heapBuffer(10);
// 直接内存
ByteBuf directBuf = allocator.directBuffer(10);
|---------|-------------|----------------|
| 对比项 | 堆内存 ByteBuf | 直接内存 ByteBuf |
| 内存位置 | JVM 堆 | JVM 堆外 |
| GC 管理 | 是 | 否 |
| IO 性能 | 慢(多一次拷贝) | 快(少一次拷贝) |
| 创建成本 | 低 | 高 |
| 是否需手动释放 | 否 | 是(release) |
Direct ByteBuf 提高 IO 性能、降低 GC 压力,但创建成本高且需要手动释放;Heap ByteBuf 管理简单,但 IO 性能差。
够
按你刚才的要求,继续**极限精简,只保留"有用信息"**👇
Netty ByteBuf:池化 vs 非池化(精简版)
复用 ByteBuf,避免频繁创建 / 销毁的事件耗费
2️⃣ 核心差异
|------------|-------------------|--------|
| 对比 | 非池化 | 池化 |
| ByteBuf 获取 | 每次 new | 从池中复用 |
| 直接内存成本 | 高(频繁 malloc/free) | 低 |
| GC / 内存压力 | 大 | 小 |
| 并发场景 | 不友好 | 友好 |
3️⃣ 启用方式
-Dio.netty.allocator.type=pooled # 池化
-Dio.netty.allocator.type=unpooled # 非池化
4️⃣ 默认策略(记结论)
- Netty 4.1+ :非 Android 默认 池化
- Android:默认非池化
- 4.1 之前:默认非池化(池化不成熟)
池化通过复用 ByteBuf 降低直接内存分配成本和 GC 压力,是 Netty 在高并发 IO 场景下的关键优化手段。
组成
ByteBuf由四部分组成
- 读指针(readerIndex):标记当前可读数据的起始位置。
- 写指针(writerIndex):标记当前可写数据的起始位置。
- 容量(capacity):当前 ByteBuf 实际占用的内存大小。
- 最大容量(maxCapacity):ByteBuf 可扩容到的最大内存限制。

相比于ByttBuffer,不用来回切换读写模式更方便,且支持动态扩容
整数大端写入端:更符合读书习惯
整数小端写入: CPU 从低位到高位的运算顺序,内存访问更连续。
ByteBuf扩容规则:
- 如果写入字节小于512,则容量下一次为16的整数倍。
- 如果写入字节大于512,则容量下一次为2^n
- 扩容后不能超过max capacity
内存释放
核心机制:引用计数 (Reference Counting)
Netty 的 ByteBuf 实现了 ReferenceCounted 接口。
- 初始状态: 创建一个新的
ByteBuf时,引用计数refCnt为 1。 - Retain (保留): 调用
buf.retain(),引用计数 +1。表示有新的地方在使用它。 - Release (释放): 调用
buf.release(),引用计数 -1。 - 回收: 当引用计数变为 0 时,Netty 会将该内存块归还给内存池(Pooled)或直接销毁(Unpooled)。
警告: 如果引用计数未归零,GC 无法回收堆外内存(Direct Memory),将直接导致 内存泄漏 (Memory Leak) 。如果引用计数归零后继续访问[即使ByteBuf对象还在,但是底层内存会被回收],会抛出 IllegalReferenceCountException。

释放时机:而在netty中一个基本原则:"谁最后使用(消费)了数据,谁就负责释放。"
Slice;切片

【零拷贝】的体现之一,对原始 ByteBuf 进行切片成多个 ByteBuf, 切片后的 ByteBuf 并没有发生内存复制,还是使用原始 ByteBuf 的内存,切片后的 ByteBuf 维护独立的 read, write 指针
逻辑上对ByteBuf进行切分,其实物理内存还是同一块
ByteBuf.slice(index1,index2)
index1:起始位置
index2:切片长度
切片共享原始内存,容量固定,原 ByteBuf 一旦释放,切片就不可用了;
写入超界会抛异常,安全使用需要正确管理引用计数。
duplicate

【零拷贝】的体现之一,就好比截取了原始 ByteBuf 所有内容,并且没有 max capacity 的限制,也是与原始ByteBuf 使用同一块底层内存,只是读写指针是独立的
零拷贝相反Copy
会将底层内存数据进行深拷贝,无论读写,都与原始ByteBuf无关
Composite
CompositeByteBuf
把多个 ByteBuf 逻辑上拼接成一个连续缓冲区
unPooled
unpooled 是 Netty 提供的一个 工具类,用来创建 非池化(unpooled)的 ByteBuf,区别于 Netty 的 池化 ByteBuf(PooledByteBuf)。它的核心作用和特点可以总结如下: