在netty中重用bytebuf(Reusing of bytebuf in netty)

编程入门 行业动态 更新时间:2024-10-26 18:21:04
netty中重用bytebuf(Reusing of bytebuf in netty)

我有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)

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

I have a http service with Netty. For a set of requests there is the same reply with just "{}" in http body. I had an idea to avoid creation of new buffer for each such request etc so I've just used:

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

in my SimpleChannelInboundHandler. It works only for first query, after it I start to have

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)

so looks like buffer is automatically released after first reply. What is a correct way to have such buffer?

最满意答案

共享Netty缓冲区时,您需要遵循基本引用计数的规则,这与基本垃圾收集的简单规则不同。

这些规则基本归结为:

从类中发送ByteBuf ,请调用retain() 如果您使用了ByteBuf ,请调用release()

大多数情况下,当您在发送它时同时使用bytebuf时,您可以删除这两个调用。

在您的示例中,在将共享的ByteBuf写入套接字时,应调用retain()来增加引用计数,因为该对象现在在2个不同的位置使用。

调用.retain()之后仍然需要做一个技巧,即调用.duplicate() ,因为这可以防止读者索引的修改传递给你的基本副本,如果不这样做会产生第一个问题写成功,但之后所有后续写操作都会写一个空缓冲区。

When sharing a Netty buffer, you need to follow the rules of basic reference counting, unlike the simple rules of basic garbage collection.

These rules basically boil down to:

When sending a ByteBuf away from your class, call retain() If you are done using a ByteBuf, call release()

Most of the times, when you are done using a bytebuf at the same time as sending it away, you can remove both calls.

Inside you example, when writing your shared ByteBuf to the socket, you should call retain() to increment the reference count, since the object is now used in 2 different places.

There is still 1 trick you need to do after calling .retain(), that is calling .duplicate(), as this prevents modifications of the reader index from passing to to your base copy, failing to do so gives the problem of the first write succeeded, but after that all subsequent writes will write an empty buffer.

更多推荐

本文发布于:2023-07-09 14:29:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1086988.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:netty   bytebuf   Reusing

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!