处理程序管道的典型引用计数

时间:2017-12-04 16:59:00

标签: netty

尝试升级到Netty 4.1.17.Final,我面临以下管道的引用计数问题。

  • 第一个处理程序正在构建来自ByteBuf的原始输入:等待至少有少量readableBytes消耗帧,将所有可以从此原始输入中读取的帧放入output(输入/输出List参数)。这些帧是派生缓冲区,使用readSlice
  • 第二个处理程序将每个帧解析为特定于应用程序的类(未计算)。

据我了解,只有第二个处理程序应该调用release()

不幸的是,在第一次尝试IllegalReferenceCountException: refCnt: 0时,它会在某些情况下(当缓冲区被回收时)引发readIntLE

我不清楚在这样的处理程序管道/链中,第一个应该是retain缓冲区,还是不使用派生缓冲区,...

编辑#1:与我从文档中理解的相反,readRetainedSlice实际上并不“与readSlice(...)的行为类似。在这种情况下,保留()”,作为{返回的缓冲区{1}}与父母的readRetainedSlice不同。

编辑#2:使用refCnt过滤泄漏检测详细信息,似乎问题出在出站端。

leakDetection.acquireAndReleaseOnly=false

1 个答案:

答案 0 :(得分:1)

所以我看了你的代码并且有一个缓冲区泄漏:

https://github.com/cchantep/ReactiveMongo/blob/49bde9b63a95b2d20f9ae44ae41104a5bf3f154c/driver/src/main/scala/core/protocol/protocol.scala#L241

这会调用frame.readBytes(readableBytes),它会返回一个新的已分配的ByteBuf,您只需将其放在地板上,而无需调用release()。虽然在这里调用release()应该解决这个漏洞,但我建议只调用frame.skipBytes(readableBytes),这也会丢弃它但没有分配和内存副本。

希望这应该解决它。

请注意我的Scala技能有点生疏,所以也许我错过了一些东西:)