Reusing of bytebuf in netty

僤鯓⒐⒋嵵緔 提交于 2020-06-23 09:31:54

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/45771169/reusing-of-bytebuf-in-netty

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!