gpt4 book ai didi

netty - netty中bytebuf的复用

转载 作者:行者123 更新时间:2023-12-02 15:08:16 25 4
gpt4 key购买 nike

我有一个 Netty 的 http 服务。对于一组请求,在 http 正文中只有“{}”的相同回复。我想避免为每个此类请求等创建新缓冲区,所以我刚刚使用了:

private static final ByteBuf EMPTY_REPLY = Unpooled.copiedBuffer("{}", CharsetUtil.UTF_8);

在我的 SimpleChannelInboundHandler 中。它仅适用于第一次查询,之后我开始拥有

WARNING: Failed to mark a promise as success because it has failed already: DefaultChannelPromise@48c81b24(failure: io.netty.handler.codec.EncoderException: io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1), unnotified cause:
io.netty.handler.codec.EncoderException: io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:106)
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:738)
at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:801)
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:814)
at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:794)
at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:831)
at travel.ServerHandler.writeResult(ServerHandler.java:475)

所以看起来缓冲区在第一次回复后自动释放。拥有此类缓冲区的正确方法是什么?

最佳答案

共享Netty buffer时,需要遵循basic reference counting的规则,不像基本垃圾收集的简单规则。

这些规则基本上归结为:

  • 当从您的类(class)发送 ByteBuf 时,调用 retain()
  • 如果您使用完 ByteBuf,请调用 release()

大多数时候,当你在发送它的同时使用完一个 bytebuf,你可以删除这两个调用。

在你的例子中,当你将共享的 ByteBuf 写入套接字时,你应该调用 retain() 来增加引用计数,因为该对象现在在 2不同的地方。

在调用 .retain() 之后,您还需要做 1 个技巧,即调用 .duplicate(),因为这可以防止对 reader 索引的修改传递给你的基本副本,如果不这样做会导致第一次写入成功的问题,但之后所有后续写入都将写入一个空缓冲区。

关于netty - netty中bytebuf的复用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45771169/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com