Netty源码分析之ByteBuf引用计数
引用计数是一种常用的内存管理机制,是指将资源的被引用次数保存起来,当被引用次数变为零时就将其释放的过程。Netty在4.x版本开始使用引用计数机制进行部分对象的管理,其实现思路并不是特别复杂,它主要涉及跟踪某个对象被引用的次数。在Netty具体代码中需要通过引用计数进行内存管理的对象,会基于ReferenceCounted接口实现,其中引用计数大于0时则代表该对象被引用不会释放,当引用计数减少到0时,该对象就会被释放。通过引用计数机制,Netty可以很好的实现内存管理,引用计数减少到0时要么直接释放内存,要么放回内存池中重复利用。
1、基本示例
下面先通过一个简单示例看下Netty中引用计数机制的使用
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf recvBuffer = (ByteBuf) msg;// 申请ByteBuf 需要主动释放
if(recvBuffer.isDirect()){
System.err.println(true);
}
PooledByteBufAllocator allocator = new PooledByteBufAllocator(true);
ByteBuf sendBuffer = allocator.buffer();//申请池化直接内存
System.err.println("sendBuffer的引用计数:"+sendBuffer.refCnt());
sendBuffer.retain();
System.err.println("sendBuffer的引用计数:"+sendBuffer.refCnt());
sendBuffer.release();
System.err.println("sendBuffer的引用计数:"+sendBuffer.refCnt());
try {
byte[] bytesReady = new byte[recvBuffer.readableBytes()];
recvBuffer.readBytes(bytesReady);
System.out.println("channelRead收到数据:"+ BytesUtils.toHexString(bytesReady));
byte[] sendBytes = new byte[] {0x7E,0x01,0x02,0x7e};
sendBuffer.writeBytes(sendBytes);
ctx.writeAndFlush(sendBuffer);
System.err.println("sendBuffer的引用计数:"+sendBuffer.refCnt());
}catch (Exception e) {
// TODO: handle exception
System.err.println(e.getMessage());
}finally {
System.err.println("recvBuffer的引用计数:"+recvBuffer.refCnt());
recvBuffer.release(); //此处需要释放
System.err.println("recvBuffer的引用计数:"+recvBuffer.refCnt());
}
}


