我有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)
所以看起来缓冲区在第一次回复后会自动释放。 有这种缓冲的正确方法是什么?
答案 0 :(得分:5)
共享Netty缓冲区时,您需要遵循basic reference counting的规则,这与基本垃圾收集的简单规则不同。
这些规则基本归结为:
ByteBuf
时,请致电retain()
ByteBuf
,请致电release()
大多数情况下,当您在发送时同时使用bytebuf时,您可以删除这两个电话。
在您的示例中,在将共享ByteBuf
写入套接字时,应调用retain()
来增加引用计数,因为该对象现在在2个不同的位置使用。
调用.retain()
之后仍然需要做一个技巧,即调用.duplicate()
,因为这可以防止读者索引的修改传递给你的基本副本,但是没有这样做第一次写入的问题成功,但之后所有后续写入都将写入一个空缓冲区。