Netty 新手关于 WARNING: Failed to release a message: PooledUnsafeDirectByteBuf(freed) 的问题
Netty neophyte question on WARNING: Failed to release a message: PooledUnsafeDirectByteBuf(freed)
我正在通过 Netty In Action 书和代码示例学习 Netty,用于 https://github.com/normanmaurer/netty-in-action/tree/2.0-SNAPSHOT/chapter2
中的第 2 章示例
我添加了另一个 AnotherEchoServerHandler
extends ChannelInboundHandlerAdapter
,在 AnotherEchoServerHandler.channelRead
方法中,我将其更新为:
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf in = (ByteBuf) msg;
System.out.println(
"Log from AnotherEchoServerHandler that Server received: " + in.toString(CharsetUtil.UTF_8));
ctx.fireChannelRead(msg);
ctx.write(in);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx)
throws Exception {
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
.addListener(ChannelFutureListener.CLOSE);
}
在 EchoServer
中,我添加了新的 ChannelHandler
作为 :
ch.pipeline().addLast(new AnotherEchoServerHandler()).addLast(serverHandler);
连同另一个 EchoServerHandler
,我现在有两个 ChannelHandler
,我想从每个 ChannelHandler
打印一条消息,并从每个 ChannelHandler
向客户端写回一条消息ChannelHandler
.
运行 上面这个改动的书例:
在服务器端,它记录:
[INFO] --- exec-maven-plugin:1.2.1:java (default-cli) @ echo-server ---
nia.chapter2.echoserver.EchoServer started and listening for connections on /0:0:0:0:0:0:0:0:8888
Log from AnotherEchoServerHandler that Server received: Netty rocks!
Server received: Netty rocks!
在客户端,它记录:
Client received: Netty rocks!Netty rocks!
如你所见,我在双方都得到了预期的信息,但我也在服务器端看到了一个警告:
Mar 30, 2021 6:25:29 PM io.netty.util.ReferenceCountUtil safeRelease
WARNING: Failed to release a message: PooledUnsafeDirectByteBuf(freed)
io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
at io.netty.buffer.AbstractReferenceCountedByteBuf.release0(AbstractReferenceCountedByteBuf.java:101)
at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:89)
at io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:84)
at io.netty.util.ReferenceCountUtil.safeRelease(ReferenceCountUtil.java:109)
at io.netty.channel.ChannelOutboundBuffer.remove(ChannelOutboundBuffer.java:256)
at io.netty.channel.ChannelOutboundBuffer.removeBytes(ChannelOutboundBuffer.java:337)
at io.netty.channel.socket.nio.NioSocketChannel.doWrite(NioSocketChannel.java:448)
at io.netty.channel.AbstractChannel$AbstractUnsafe.flush0(AbstractChannel.java:856)
at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.flush0(AbstractNioChannel.java:362)
at io.netty.channel.AbstractChannel$AbstractUnsafe.flush(AbstractChannel.java:823)
at io.netty.channel.DefaultChannelPipeline$HeadContext.flush(DefaultChannelPipeline.java:1296)
at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:776)
at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:802)
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 nia.chapter2.echoserver.AnotherEchoServerHandler.channelReadComplete(AnotherEchoServerHandler.java:30)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelReadComplete(AbstractChannelHandlerContext.java:398)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelReadComplete(AbstractChannelHandlerContext.java:380)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelReadComplete(AbstractChannelHandlerContext.java:373)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelReadComplete(DefaultChannelPipeline.java:1339)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelReadComplete(AbstractChannelHandlerContext.java:398)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelReadComplete(AbstractChannelHandlerContext.java:380)
at io.netty.channel.DefaultChannelPipeline.fireChannelReadComplete(DefaultChannelPipeline.java:932)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:139)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:644)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:579)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:496)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:458)
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:858)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
at java.lang.Thread.run(Thread.java:748
这条警告消息是什么意思? 如何避免它?
Along with the other EchoServerHandler, I have two ChannelHandler now, I'd like to print a message from each ChannelHandler, and write back a message to Client from each ChannelHandler.
EchoServerHandler
也会写成msg
。这将导致 msg
在 ChannelOutboundBuffer
中被释放两次。
您可以在写入 AnotherEchoServerHandler
之前删除 EchoServerHandler
或调用 in.retain()
我正在通过 Netty In Action 书和代码示例学习 Netty,用于 https://github.com/normanmaurer/netty-in-action/tree/2.0-SNAPSHOT/chapter2
中的第 2 章示例我添加了另一个 AnotherEchoServerHandler
extends ChannelInboundHandlerAdapter
,在 AnotherEchoServerHandler.channelRead
方法中,我将其更新为:
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf in = (ByteBuf) msg;
System.out.println(
"Log from AnotherEchoServerHandler that Server received: " + in.toString(CharsetUtil.UTF_8));
ctx.fireChannelRead(msg);
ctx.write(in);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx)
throws Exception {
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
.addListener(ChannelFutureListener.CLOSE);
}
在 EchoServer
中,我添加了新的 ChannelHandler
作为 :
ch.pipeline().addLast(new AnotherEchoServerHandler()).addLast(serverHandler);
连同另一个 EchoServerHandler
,我现在有两个 ChannelHandler
,我想从每个 ChannelHandler
打印一条消息,并从每个 ChannelHandler
向客户端写回一条消息ChannelHandler
.
运行 上面这个改动的书例:
在服务器端,它记录:
[INFO] --- exec-maven-plugin:1.2.1:java (default-cli) @ echo-server ---
nia.chapter2.echoserver.EchoServer started and listening for connections on /0:0:0:0:0:0:0:0:8888
Log from AnotherEchoServerHandler that Server received: Netty rocks!
Server received: Netty rocks!
在客户端,它记录:
Client received: Netty rocks!Netty rocks!
如你所见,我在双方都得到了预期的信息,但我也在服务器端看到了一个警告:
Mar 30, 2021 6:25:29 PM io.netty.util.ReferenceCountUtil safeRelease
WARNING: Failed to release a message: PooledUnsafeDirectByteBuf(freed)
io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
at io.netty.buffer.AbstractReferenceCountedByteBuf.release0(AbstractReferenceCountedByteBuf.java:101)
at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:89)
at io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:84)
at io.netty.util.ReferenceCountUtil.safeRelease(ReferenceCountUtil.java:109)
at io.netty.channel.ChannelOutboundBuffer.remove(ChannelOutboundBuffer.java:256)
at io.netty.channel.ChannelOutboundBuffer.removeBytes(ChannelOutboundBuffer.java:337)
at io.netty.channel.socket.nio.NioSocketChannel.doWrite(NioSocketChannel.java:448)
at io.netty.channel.AbstractChannel$AbstractUnsafe.flush0(AbstractChannel.java:856)
at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.flush0(AbstractNioChannel.java:362)
at io.netty.channel.AbstractChannel$AbstractUnsafe.flush(AbstractChannel.java:823)
at io.netty.channel.DefaultChannelPipeline$HeadContext.flush(DefaultChannelPipeline.java:1296)
at io.netty.channel.AbstractChannelHandlerContext.invokeFlush0(AbstractChannelHandlerContext.java:776)
at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:802)
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 nia.chapter2.echoserver.AnotherEchoServerHandler.channelReadComplete(AnotherEchoServerHandler.java:30)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelReadComplete(AbstractChannelHandlerContext.java:398)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelReadComplete(AbstractChannelHandlerContext.java:380)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelReadComplete(AbstractChannelHandlerContext.java:373)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelReadComplete(DefaultChannelPipeline.java:1339)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelReadComplete(AbstractChannelHandlerContext.java:398)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelReadComplete(AbstractChannelHandlerContext.java:380)
at io.netty.channel.DefaultChannelPipeline.fireChannelReadComplete(DefaultChannelPipeline.java:932)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:139)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:644)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:579)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:496)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:458)
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:858)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
at java.lang.Thread.run(Thread.java:748
这条警告消息是什么意思? 如何避免它?
Along with the other EchoServerHandler, I have two ChannelHandler now, I'd like to print a message from each ChannelHandler, and write back a message to Client from each ChannelHandler.
EchoServerHandler
也会写成msg
。这将导致 msg
在 ChannelOutboundBuffer
中被释放两次。
您可以在写入 AnotherEchoServerHandler
EchoServerHandler
或调用 in.retain()