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

Netty 4中的缓冲区所有权:如何管理缓冲区生命周期?,netty,Netty,我一直在尝试编写一个HTTP客户端来同时获取多个提要(最多1k),这也是学习Netty 4的一个练习 我的问题是,是否有一个很好的解释来解释新的ByteBuf基础设施是如何工作的?谁“拥有”它们,它们是如何共享的(是吗?)?ChannelPipeline中的每个ChannelHandler都有自己的ByteBuf吗 下面是一个让我感到困惑的例子: 我向HTTP客户端管道添加了以下类的实例: public class MyFilter extends MessageToMessageDecoder

我一直在尝试编写一个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;
}
公共类MyFilter扩展MessageToMessageDecoder{
@凌驾
受保护对象解码(ChannelHandlerContext ctx、HttpObject msg)引发异常{
//做一些工作,但保持味精不变
BufUtil.retain(msg);//为什么我需要调用BufUtil.retain(msg)???
返回味精;
}

如果我不在msg上调用BufUtil.retain,它似乎会得到GCd,我会得到各种虚假错误。

HttpContent
扩展
ReferenceCounted
以跟踪它所持有的缓冲区的生命周期。当
ReferenceCounted
被实例化时,它的生命开始于
1
refCnt
。如果在其上调用
retain()
refCnt
增加。
refCnt
release()
上减少,并且在
refCnt
变为
0
后,底层资源(
ByteBuf
在本例中)将被销毁

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

为了避免很难追踪的泄漏,扩展
SimpleChannelInboundHandler
,它在处理消息后自动调用
release()


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

您好,谢谢。在性能至关重要的环境中,这是有意义的。如果能更明显的话…@trustin-我也对所有这些引用感到困惑和惊讶,因为这些引用都渗透到了用户API中。也许您可以使用一个熟悉的Java构造来代替:资源,就像在try with resources中一样。或者让消息对象的行为与用户默认期望的一样,只通过一个单独的接口获得高度性能优化但更复杂的版本;性能不如使用c快速构建应用程序重要Rayon,如果有一种明确的方法来指定java中对象的生命周期,比如C++中的析构函数,那么我们就绝不会需要为大多数情况引入引用计数。然而,java没有这样的东西,因此引用计数是管理缓冲区的最有效的方法。etty,但不幸的是,这是安全处理直接缓冲区的唯一方法。顺便说一句,Netty中的缓冲区泄漏相对容易找到:@smwikipedia”或“应该是”,因此“确实是。谢谢你的建议。@smwikipedia对于你提到的线程,我想选择的答案已经很好了。