创建地点:NioByteUnsafe#read
public final void read() {
final ChannelConfig config = config();
final ChannelPipeline pipeline = pipeline();
final ByteBufAllocator allocator = config.getAllocator();
final RecvByteBufAllocator.Handle allocHandle = recvBufAllocHandle();
allocHandle.reset(config);
ByteBuf byteBuf = null;
boolean close = false;
try {
do {
// 申请了buf
byteBuf = allocHandle.allocate(allocator);
。。。
。。。
回收地点:TailContext#channelRead
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
onUnhandledInboundMessage(msg);
}
protected void onUnhandledInboundMessage(Object msg) {
try {
logger.debug(
"Discarded inbound message {} that reached at the tail of the pipeline. " +
"Please check your pipeline configuration.", msg);
} finally {
// 释放buffer
ReferenceCountUtil.release(msg);
}
}
SimpleChannelInboundHandler#read
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
boolean release = true;
try {
if (acceptInboundMessage(msg)) {
@SuppressWarnings("unchecked")
I imsg = (I) msg;
channelRead0(ctx, imsg);
} else {
release = false;
ctx.fireChannelRead(msg);
}
} finally {
if (autoRelease && release) {
// 释放
ReferenceCountUtil.release(msg);
}
}
}
- Netty默认会在ChannelPipline的最后添加一个tail handler帮你完成ByteBuf的release。
- SimpleChannelInboundHandler的read方法会释放msg
- 其释放的是channelRead传入的ByteBuf,如果在handlers传递过程中,传递了新值,老值需要你自己手动释放。
- 另外如果中途没有使用fireChannelRead传递下去也要自己释放。