netty的异常分析 IllegalReferenceCountException refCnt: 0, decrement: 1
来源:互联网 发布:初中学历能学编程吗 编辑:程序博客网 时间:2024/06/05 08:10
在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);
阅读全文
0 0
- netty的异常分析 IllegalReferenceCountException refCnt: 0, decrement: 1
- netty 错误 #[IllegalReferenceCountException: refCnt: 0, decrement: 1]
- REFCNT
- 关于netty源码的分析
- Netty源码分析系列1——NIOEventLoopGroup的创建
- 基于Netty的HTTP通信研究分析
- netty中ByteBuf部分的分析
- 基于Netty的HTTP通信研究分析
- Storm netty client溢出的bug分析
- Netty的启动执行过程分析(一)
- Netty的启动执行过程分析(二)
- 处理一个netty异常
- Netty EventLoop与EventExecutor分析(1)
- Netty源码分析1 -- 服务器启动
- netty源码分析(三)Netty服务端ServerBootstrap的初始化与反射在其中的应用分析
- 追踪 Netty 异常占用堆外内存的经验分享
- [netty源码分析]--EventLoopGroup与EventLoop 分析netty的线程模型
- netty源码分析(二)Netty对Executor的实现机制源码分析
- centos7.2安装oracle11g r2
- Hibernate开发前准备
- Linux安全扫描概述
- fping概述及源码包编译原理
- JSP的pageContext对象和config对象
- netty的异常分析 IllegalReferenceCountException refCnt: 0, decrement: 1
- JSP的Eception
- JSP实现用户登录
- 多渠道打包(获取不同配置文件)
- fping命令应用
- 主机扫描命令hping
- 深入理解Java中的final关键字
- JavaBean简介及设计原则
- 图像处理我是这样入门的------我的第一篇csdn博文