10

我一直在尝试编写一个 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,我会得到各种虚假错误。

4

1 回答 1

9

HttpContent扩展ReferenceCounted以跟踪它所持有的缓冲区的生命周期。当 aReferenceCounted被实例化时,它以refCntof开始它的生命1。如果你调用retain()它,refCnt是增加的。 refCnt在 上减少release(),并且底层资源(ByteBuf在这种情况下)一旦refCnt变为 就被销毁0

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

为避免难以追踪的泄漏,请在处理完消息后自动对消息进行SimpleChannelInboundHandler扩展。release()

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

于 2013-04-04T08:17:53.930 回答