在websocket关闭时经常会抛出如下异常: IllegalReferenceCountException refCnt: 0, decrement: 1

io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:101)at io.netty.buffer.DefaultByteBufHolder.release(DefaultByteBufHolder.java:73)at io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:59)at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:112)at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:318)at io.netty.channel.AbstractChannelHandlerContext.access$600(AbstractChannelHandlerContext.java:42)at io.netty.channel.AbstractChannelHandlerContext$7.run(AbstractChannelHandlerContext.java:309)at io.netty.util.concurrent.DefaultEventExecutor.run(DefaultEventExecutor.java:36)at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112)at java.lang.Thread.run(Unknown Source)

原来是在服务器收到CloseWebSocketFrame后,SimpleChannelInboundHandler调用release时,会触发CloseWebSocketFrame.release()

public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
{boolean release = true;try {if (acceptInboundMessage(msg)){Object imsg = msg;channelRead0(ctx, imsg);} else {release = false;ctx.fireChannelRead(msg);}} finally {if ((this.autoRelease) && (release))ReferenceCountUtil.release(msg);//这行}
}

通过逐步debug,发现WebSocketServerHandler报异常的代码在handleWebSocketFrame方法中:

     if (frame instanceof CloseWebSocketFrame) {CloseWebSocketFrame close=(CloseWebSocketFrame) frame.retain()//这行handshaker.close(ctx.channel(),close);return;}

跟踪发现,它调用了AbstractReferenceCountedByteBuf

public ByteBuf retain()
{while (true) {int refCnt = this.refCnt;if (refCnt == 0) {throw new IllegalReferenceCountException(0, 1)//这行}if (refCnt == 2147483647) {throw new IllegalReferenceCountException(2147483647, 1);}if (refCntUpdater.compareAndSet(this, refCnt, refCnt + 1)) {break;}}return this;
}

在netty4中,对象的生命周期由引用计数器控制,ByteBuf就是如此,每个对象的初始化引用计数为1,调用一次release方法,引用计数器会减1,当尝试访问计数器为0的,对象时,会抛出IllegalReferenceCountException,正如ensureAccessible的实现,更加详细的解释可以参考官方文档

所以需要在对象CloseWebSocketFrame的初始化时引用人为+1

在ProtobufVarint32FrameDecoder中添加如下标红代码:

//CloseWebSocketFrame/**
*  Be aware that you need to call {@link io.netty.util.ReferenceCounted#retain()} on messages that are just passed through if they
* are of type {@link io.netty.util.ReferenceCounted}. This is needed as the {@link MessageToMessageDecoder} will call
* {@link io.netty.util.ReferenceCounted#release()} on decoded messages.
* 具体参考:
*/
ReferenceCountUtil.retain(frame);//这行
out.add(frame);

要读取当前的引用计数值用

ByteBuf.refCnt()

netty的异常分析 IllegalReferenceCountException refCnt: 0, decrement: 1相关推荐

  1. netty4 io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1

    在netty4中,对象的生命周期由引用计数器控制,ByteBuf就是如此,每个对象的初始化引用计数加1,调用一次release方法,引用计数器会减1,当尝试访问计数器为0时,对象时,会抛出Illega ...

  2. 关于netty的IllegalReferenceCountException refCnt: 0, decrement: 1

    用netty做websocket广播的时候,发现两个玩家的时候,各自单独的消息广播没有问题,当消息群发的时候就出问题,其他人收不到,然后就出现IllegalReferenceCountExceptio ...

  3. netty 错误 #[IllegalReferenceCountException: refCnt: 0, decrement: 1]

    io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1 今天写了个ping/pong的服务器和客户端玩 但是出现了以 ...

  4. netty报错 io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1

    netty报错,报错信息如下: io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1 这是因为SimpleChan ...

  5. IllegalReferenceCountException: refCnt: 0, decrement: 1

    记录一次线上报错:IllegalReferenceCountException: refCnt: 0, decrement: 1 2021-12-28 16:00:46,606 [reactor-ht ...

  6. 关于netty的中nettyio.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1异常排除

    通常引起异常的原因是因为netty的计数的机制, 在服务器收到CloseWebSocketFrame后,SimpleChannelInboundHandler调用release时,会触发CloseWe ...

  7. 7. 成功解决:io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1

    ❤️ 个人主页:水滴技术

  8. netty解决方法 io.netty.util.IllegalReferenceCountException: refCnt: 0, increment: 1

    netty解决方法 io.netty.util.IllegalReferenceCountException: refCnt: 0, increment: 1 参考文章: (1)netty解决方法 i ...

  9. Netty源码分析第6章(解码器)----第4节: 分隔符解码器

    Netty源码分析第6章(解码器)---->第4节: 分隔符解码器 Netty源码分析第六章: 解码器 第四节: 分隔符解码器 基于分隔符解码器DelimiterBasedFrameDecode ...

最新文章

  1. Python 输出的空格问题
  2. Design Compiler指南——设计综合过程
  3. 通过OmniFaces缓存组件以编程方式缓存PrimeFaces图表
  4. JAVA进阶开发之(String字符串的存储原理)
  5. 基于Nginx反向代理及负载均衡
  6. pythonopencv测距_python opencv单目测距 小孔成像原理
  7. 排版小知识 1.针对某个对象对齐
  8. java 线程池的使用_Java 使用线程池执行若干任务
  9. c jni 调用java_JNI NDK (AndroidStudio+CMake )实现C C++调用Java代码流程
  10. PostgreSQL在何处处理 sql查询之二十五
  11. mysql数据库存储过程异常处理
  12. 【数据结构实验题】0/1背包问题的递归求解(注意输出所选物品下标的方法)
  13. XSD文件详解(以Maven为例)
  14. 查重有风险,小心论文被买卖!——iThenticate官方论文查重系统登录中国!
  15. linux与ipad传输文件,实用!三种iPhone与Windows电脑互传文件操作技巧,建议收藏...
  16. 收到短信:【淘会员】加微信免费赠礼品!是什么套路?这类短信如何发
  17. 那些令人虎躯一震的排序算法MATLAB实现
  18. Verilog实现之任意分频电路
  19. DSAPI多功能.NET函数库组件
  20. 计算物品的良率(python)

热门文章

  1. Nordic nRF52832申报要素
  2. 阿里云安全组是什么?如何配置安全组(图文教程)?
  3. 科学计算机 app,‎App Store 上的“超级计算器-科学计算机”
  4. SitePoint播客#158:饮酒与技术
  5. 【C语言】打印图案总结
  6. Android Studio项目编码设置为GBK或UTF-8  中文乱码 和 Eclipse项目编码设置
  7. 经常使用传感器协议3:CJ/T-188 冷热量表协议解析2
  8. 益智java单词游戏_java实现单词搜索迷宫游戏
  9. 2021开年巨作!JDBC连接数据库工具类!
  10. GB28181实现对安防摄像头的直播回放控制