netty 中有堆外内存,需要手动释放。
UnpooledHeapByteBuf- 使用
JVM内存,等待GC回收即可
- 使用
UnpooledDirectByteBuf- 使用直接内存,需要特殊方法回收
PooledByteBuf和子类- 使用了池化机制,需要更复杂的规则回收 「重用」
无论是上面那种回收,netty 提供了一个统一的接口 ReferenceCounted 接口
- 每个
ByteBuf对象初始计数为1 - 调用
release方法减1,如果计数为0,则ByteBuf内存被回收 - 调用
retain方法加1 - 当计数为
0时,底层内存会被回收,这样即使ByteBuf对象还在,各个方法也不能被使用
release
1 | ByteBuf b = ... |
上面这种做法通常是不对的,因为 pipeline 的存在,一般需要把 ByteBuf 传递给下一个 ChannelHandler 中,如果在 finally 使用 release 就是去了传递性。
所以,谁最后用 ByteBuf ,谁就 release。
头尾释放
ChannelHandler 中有 head -> handler1 -> handler2 -> tail
实际上,head 和 tail 已经自动进行 release 了。