0%

java | 内存释放

netty 中有堆外内存,需要手动释放。

  • UnpooledHeapByteBuf
    • 使用 JVM 内存,等待 GC 回收即可
  • UnpooledDirectByteBuf
    • 使用直接内存,需要特殊方法回收
  • PooledByteBuf和子类
    • 使用了池化机制,需要更复杂的规则回收 「重用」

无论是上面那种回收,netty 提供了一个统一的接口 ReferenceCounted 接口

  • 每个 ByteBuf 对象初始计数为 1
  • 调用 release 方法减 1,如果计数为 0,则 ByteBuf 内存被回收
  • 调用 retain 方法加 1
  • 当计数为 0 时,底层内存会被回收,这样即使 ByteBuf 对象还在,各个方法也不能被使用

release

1
2
3
4
5
6
7
ByteBuf b = ...

try{

}finally{
b.release();
}

上面这种做法通常是不对的,因为 pipeline 的存在,一般需要把 ByteBuf 传递给下一个 ChannelHandler 中,如果在 finally 使用 release 就是去了传递性。

所以,谁最后用 ByteBuf ,谁就 release

头尾释放

ChannelHandler 中有 head -> handler1 -> handler2 -> tail

实际上,headtail 已经自动进行 release 了。

请我喝杯咖啡吧~