❤️ 个人主页:水滴技术
🌸 订阅专栏:成功解决 BUG 合集
🚀 支持水滴:点赞👍 + 收藏⭐ + 留言💬
问题描述
今天使用 Netty 搭建一个项目,接收报文时提示如下错误:io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
at io.netty.util.internal.ReferenceCountUpdater.toLiveRealRefCnt(ReferenceCountUpdater.java:83) ~[netty-common-4.1.82.Final.jar:4.1.82.Final]
at io.netty.util.internal.ReferenceCountUpdater.release(ReferenceCountUpdater.java:147) ~[netty-common-4.1.82.Final.jar:4.1.82.Final]
at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:101) ~[netty-buffer-4.1.82.Final.jar:4.1.82.Final]
at io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:90) ~[netty-common-4.1.82.Final.jar:4.1.82.Final]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:106) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
at io.netty.channel.AbstractChannelHandlerContext.access$600(AbstractChannelHandlerContext.java:61) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
at io.netty.channel.AbstractChannelHandlerContext$7.run(AbstractChannelHandlerContext.java:370) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
at io.netty.util.concurrent.AbstractEventExecutor.runTask$$$capture(AbstractEventExecutor.java:174) [netty-common-4.1.82.Final.jar:4.1.82.Final]
at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java) [netty-common-4.1.82.Final.jar:4.1.82.Final]
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute$$$capture(AbstractEventExecutor.java:167) [netty-common-4.1.82.Final.jar:4.1.82.Final]
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java) [netty-common-4.1.82.Final.jar:4.1.82.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470) [netty-common-4.1.82.Final.jar:4.1.82.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569) [netty-transport-4.1.82.Final.jar:4.1.82.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) [netty-common-4.1.82.Final.jar:4.1.82.Final]
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) [netty-common-4.1.82.Final.jar:4.1.82.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-common-4.1.82.Final.jar:4.1.82.Final]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_251]
原因分析
该异常为非法的引用计数异常,我的代码确定是用到了ReferenceCountUtil.release(msg)来释放ByteBuf。这是官网推荐使用的,为什么这次就有问题呢?
之前项目中使用的是 ChannelInboundHandlerAdapter
作为入站处理器,这次使用的是 SimpleChannelInboundHandler
。看了看SimpleChannelInboundHandler
的源码,找到了原因。
在 SimpleChannelInboundHandler
的 channelRead
方法中可以看出,它已经对ByteBuf
进行释放了,我们自己再释放一次肯定会报错的了。
解决方案
把自己代码中的 ReferenceCountUtil.release(msg)
给去掉就可以了。
注:使用 ChannelInboundHandlerAdapter
时必须要手动释放;使用 SimpleChannelInboundHandler
时无需手动释放,它已经帮我们自动释放了。