Netty出现的异常【已解决】:An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
-
修改方案:
byteBuf.retain();ByteBuf后面添加这个retain(),这个添加原则是这样,如果你消耗了一次ByteBuf,你的下游Handler还需要再次消耗的话,就需要添加这个retain(),以此类推,一定要要注意添加的时机,不然的话可能需要自己手动释放; -
原因分析:这个错误是因为
ByteBuf的已经被逻辑释放了,重复释放导致的;Netty为了防止内存泄漏,使用引用计数的方式计算;这个引用计数一般再ByteBuf创建的时候会有一次,任何一次的读,写操作都会导致引用数-1;当引用数为0时,在进行读写操作,肯定是不行的,所以如果不注意,很容易出现这个错误;而这个retain会增加一次引用,也就是可以再使用一次;这样就避免了这个异常发生;-
回到我自己的项目案例:
-
我创建了一个顶级的父类
NioWebSocketFrameHandler,用来处理WebSocketFrame数据帧数据,进行最初的数据分发处理;下面是比较关键的方法:
![]()
-
这里我将数据投递到下一个
handler,这里会消耗一次ByteBuf;(所以理论上这里的ByteBuf是可以被回收了);我们继续看下一个处理器,用来处理二进制的数据帧,红框框的位置就是出现异常的位置
![]()
-
前面我们说过,ByteBuf的每一次读取都会消耗一次引用,再上游的时候,就已经消耗了一次引用,而
ByteBuf的引用是整个Pipeline共享的,所以这里的ByteBuf肯定是不能再引用数-1操作的,引用数已经是0了(这个操作是netty自动完成的),所以就出现了异常错误;
-
-
最后补充一句,当Bytefue引用数为0的时候,Netty会自动回收,所以有时候会出现空指针异常,也是这个原因;源码分析就这里就不分析了,感兴趣的可以去看看;



浙公网安备 33010602011771号