Netty 4中的缓冲区所有权:如何管理缓冲区生命周期?

时间:2013-04-03 07:25:56

标签: netty

我一直在尝试编写一个HTTP客户端来同时获取多个提要(最多1k),这也是学习Netty 4的练习。

我的问题是,如果有一个很好的解释,新的ByteBuf基础设施如何工作?谁“拥有”他们,他们是如何分享的(是吗?)? ChannelPipeline中的每个ChannelHandler都有它自己的ByteBuf吗?

这是一个令我困惑的例子:

我在HTTP客户端管道中添加了以下类的实例:

public class MyFilter extends MessageToMessageDecoder<HttpObject> {

    @Override
    protected Object decode(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
        // do some work, but leave msg unchanged
        BufUtil.retain(msg); // Why do I need to call BufUtil.retain(msg) ???
        return msg;
}

如果我没有在msg上调用BufUtil.retain,它似乎得到了GCd,我得到了各种各样的虚假错误。

1 个答案:

答案 0 :(得分:8)

HttpContent扩展ReferenceCounted以跟踪它所拥有的缓冲区的生命周期。实例化ReferenceCounted后,它会以refCnt的{​​{1}}开始生效。如果您在其上调用1,则retain()会增加。 refCntrefCnt已减少,release()变为ByteBuf后,基础资源(本例中为refCnt)将被销毁。

通常,处理程序不需要保留对它完成处理的消息的引用,因为消息通常被丢弃或在处理后转换为其他内容。因此,一旦您的处理程序完成,就必须在消息上调用0方法。这通常容易出错,并且很容易导致资源泄漏。

为了避免非常难以追踪的泄漏,请在处理完消息时自动调用release() {/ 1}}。

有关Netty中引用计数的更多信息,请阅读this wiki page。它还通过使用Netty的缓冲区泄漏检测机制为您提供有关如何排除缓冲区泄漏的详细信息。