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
了。