上一篇講過,收發的數據都會先放入內存,並且這個內存還會是JVM以外的直接內存,所以需要我們手動去回收。
回收接收數據
如下,msg和in是兩個不同的變量,但是都引用同一個對象,回收in或msg效果是一樣的。
public void channelRead(ChannelHandlerContext ctx, Object msg) {
try {
ByteBuf in = (ByteBuf) msg;
//業務處理
} finally {
ReferenceCountUtil.release(msg); //回收
}
回收發出數據
發出數據時,需要調用flush,這個方法會自動幫你回收發出的數據,所以不用手動回收。
SimpleChannelInboundHandler
接收的數據也可以自動回收,只需用SimpleChannelInboundHandler替代ChannelInboundHandlerAdapter,當執行完channelRead0後,msg就會被回收。
public class NettyServerHandler extends SimpleChannelInboundHandler<Object> {
protected void channelRead0(ChannelHandlerContext ctx, Object msg) {
}
可以看下SimpleChannelInboundHandler的部分源碼,接收消息時首先會調用它的channelRead,然後再調用你的channelRead0,最後它幫你實現了回收。關於if塊的內容,是檢查消息類型是否匹配,不匹配就交給下一個Handler去處理,以後再介紹。
public abstract class SimpleChannelInboundHandler<I> extends ChannelInboundHandlerAdapter {
.....
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);
}
}