Netty 4.1.6(io.netty:netty-all:4.1.6.Final来自Gradle通过jcenter(),在OS X 10.11.6上使用Java 1.8.0_102)声明这是一个警告,但它实际上导致我的代码不做正确的事情。作为Netty的新手,我几乎肯定搞砸了,所以我想我会问专家。
我明白了:
[nioEventLoopGroup-2-1] WARN io.netty.util.ReferenceCountUtil - Failed to release a message: DatagramPacket(=> /127.0.0.1:54169, PooledUnsafeDirectByteBuf(freed))
io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
来自此代码:
public void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
ByteBuf bb = Unpooled.copiedBuffer(packet.content());
String ssHex = javax.xml.bind.DatatypeConverter.printHexBinary(bb.array());
System.out.println("IP:"+packet.sender()+":"+packet.recipient()+":"+ssHex);
DatagramPacket udpPacket = new DatagramPacket(packet.content(), packet.sender()); // Using this line causes the exception at write
//DatagramPacket udpPacket = new DatagramPacket(bb, packet.sender()); // Using this line succeeds
ctx.write(udpPacket); // Exception is thrown here
}
我做错了什么?谢谢你的帮助。
完全例外:
[nioEventLoopGroup-2-1] WARN io.netty.util.ReferenceCountUtil - Failed to release a message: DatagramPacket(=> /127.0.0.1:54169, PooledUnsafeDirectByteBuf(freed))
io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
at io.netty.buffer.AbstractReferenceCountedByteBuf.release0(AbstractReferenceCountedByteBuf.java:110)
at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:98)
at io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:84)
at io.netty.channel.DefaultAddressedEnvelope.release(DefaultAddressedEnvelope.java:101)
at io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:84)
at io.netty.util.ReferenceCountUtil.safeRelease(ReferenceCountUtil.java:109)
at io.netty.channel.ChannelOutboundBuffer.remove0(ChannelOutboundBuffer.java:296)
at io.netty.channel.ChannelOutboundBuffer.failFlushed(ChannelOutboundBuffer.java:621)
at io.netty.channel.AbstractChannel$AbstractUnsafe.flush0(AbstractChannel.java:869)
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:787)
at io.netty.channel.AbstractChannelHandlerContext.invokeFlush(AbstractChannelHandlerContext.java:779)
at io.netty.channel.AbstractChannelHandlerContext.flush(AbstractChannelHandlerContext.java:760)
at com.foobar.uservices.initial_receiver.InitialReceiverHandler.channelReadComplete(InitialReceiverHandler.java:24)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelReadComplete(AbstractChannelHandlerContext.java:409)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelReadComplete(AbstractChannelHandlerContext.java:391)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelReadComplete(AbstractChannelHandlerContext.java:384)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelReadComplete(DefaultChannelPipeline.java:1339)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelReadComplete(AbstractChannelHandlerContext.java:409)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelReadComplete(AbstractChannelHandlerContext.java:391)
at io.netty.channel.DefaultChannelPipeline.fireChannelReadComplete(DefaultChannelPipeline.java:932)
at io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read(AbstractNioMessageChannel.java:97)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:651)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:574)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:488)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:450)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:873)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
at java.lang.Thread.run(Thread.java:745)
答案 0 :(得分:2)
很难从您的代码中看出,但看起来您可能正在使用SimpleChannelInboundHandler,它会自动释放任何传入的消息。由于您传递的是相同的缓冲区(只是以不同方式包装),因此需要在缓冲区上执行ReferenceCountUtil.retain()。
注释掉的行成功,因为它是初始缓冲区的副本,因此它具有自己的引用计数。
文档: https://netty.io/4.0/api/io/netty/channel/SimpleChannelInboundHandler.html