在netty中重用bytebuf [英] Reusing of bytebuf in netty

查看:156
本文介绍了在netty中重用bytebuf的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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);

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

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 缓冲区时,需要遵循 基本引用计数,不同于基本垃圾收集的简单规则.

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:

  • 当从你的班级发送一个 ByteBuf 时,调用 retain()
  • 如果您使用完 ByteBuf,请调用 release()
  • 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.

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

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.

在调用 .retain() 之后,你仍然需要做 1 个技巧,那就是调用 .duplicate(),因为这可以防止对读取器索引的修改传递给您的基本副本,否则会出现第一次写入成功的问题,但之后所有后续写入都将写入一个空缓冲区.

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.

这篇关于在netty中重用bytebuf的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆