netty的异常分析 IllegalReferenceCountException refCnt: 0, decrement: 1

简介: netty的异常分析 IllegalReferenceCountException refCnt: 0, decrement: 1

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

io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
  at 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()
目录
相关文章
|
6月前
|
Java
【Netty 网络通信】Netty 工作流程分析
【1月更文挑战第9天】Netty 工作流程分析
|
6月前
|
Java Unix Linux
【Netty技术专题】「原理分析系列」Netty强大特性之Native transports扩展开发实战
当涉及到网络通信和高性能的Java应用程序时,Netty是一个强大的框架。它提供了许多功能和组件,其中之一是JNI传输。JNI传输是Netty的一个特性,它为特定平台提供了高效的网络传输。 在本文中,我们将深入探讨Netty提供的特定平台的JNI传输功能,分析其优势和适用场景。我们将介绍每个特定平台的JNI传输,并讨论其性能、可靠性和可扩展性。通过了解这些特定平台的JNI传输,您将能够更好地选择和配置适合您应用程序需求的网络传输方式,以实现最佳的性能和可靠性。
143 7
【Netty技术专题】「原理分析系列」Netty强大特性之Native transports扩展开发实战
7. 成功解决:io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
今天使用 Netty 搭建一个项目,接收报文时提示如下错误:`io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1`
1517 1
|
6月前
|
前端开发 网络协议 Java
Netty | 工作流程图分析 & 核心组件说明 & 代码案例实践
Netty | 工作流程图分析 & 核心组件说明 & 代码案例实践
331 0
|
前端开发
Netty4 读写水位控制分析
Netty4 读写水位控制分析
80 0
|
运维 Java
高并发下Netty4底层bug导致直接内存溢出分析
高并发下Netty4底层bug导致直接内存溢出分析
191 0
|
编解码 前端开发 Java
源码分析Netty:核心组件及启动过程分析
本篇从实例出发,了解Netty核心组件的概念、作用及串联过程。从概念到设计原理,再到深入了解实现细节,从而能够清晰地掌握Netty的技术细节甚至存在的问题,才能最终更好地支持我们实际的各项业务。
350 0
|
存储 Java Unix
【Netty技术专题】「原理分析系列」Netty强大特性之ByteBuf零拷贝技术原理分析
【Netty技术专题】「原理分析系列」Netty强大特性之ByteBuf零拷贝技术原理分析
196 0
【Netty技术专题】「原理分析系列」Netty强大特性之ByteBuf零拷贝技术原理分析
|
网络协议 前端开发 Java
Netty服务端启动流程分析
Netty服务端启动流程分析
172 0
|
搜索推荐 网络协议 Java
一个低级错误引发Netty编码解码中文异常
最近在调研Netty的使用,在编写编码解码模块的时候遇到了一个中文字符串编码和解码异常的情况,后来发现是笔者犯了个低级错误。这里做一个小小的回顾。
562 0
一个低级错误引发Netty编码解码中文异常