在netty中重用bytebuf

时间:2017-08-19 11:48:31

标签: 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)

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

1 个答案:

答案 0 :(得分:5)

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

这些规则基本归结为:

  • 从您的班级发送ByteBuf时,请致电retain()
  • 如果您已完成使用ByteBuf,请致电release()

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

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

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