netty做上位机主动同时连接多个下位机时,接受报文报 java.lang.IndexOutOfBoundsException: srcIndex: 0异常错误

   在用netty框架做采集程序时,控制台有时会输出  WARN  io.netty.channel.AbstractChannelHandlerContext -Failed to mark a promise as failure because it has failed already: DefaultChannelPromise@630e0515(failure: java.lang.IndexOutOfBoundsException: srcIndex: 0), unnotified cause: java.lang.IndexOutOfBoundsException: srcIndex: 0 异常。
   在刚开始的时候以为是程序哪个地方出现下标越界的异常,排查后未发现相关问题,紧接着查看控制台打印的其他错误异常,发现有一个io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1的异常,百度后才知道其异常的根本原因是:
       这是因为Netty有引用计数器的原因,自从Netty 4开始,对象的生命周期由它们的引用计数(reference counts)管理,而不是由垃圾收集器(garbage collector)管理了。ByteBuf是最值得注意的,它使用了引用计数来改进分配内存和释放内存的性能。在我们创建ByteBuf对象后,它的引用计数是1,当你释放(release)引用计数对象时,它的引用计数减1,如果引用计数为0,这个引用计数对象会被释放(deallocate),并返回对象池。当尝试访问引用计数为0的引用计数对象会抛出IllegalReferenceCountException异常:
/** 
* Should be called by every method that tries to access the buffers content to check 
* if the buffer was released before. 
*/ 
protected final void ensureAccessible() { 
    if (checkAccessible && refCnt() == 0) { 
        throw new IllegalReferenceCountException(0); 
    } 
}

解决办法

方法1:在合适的地方,补上 ByteBuf.retain(),这个意思是 让netty的引用计数+1
       方法2:使用ChannelInboundHandlerAdapter替代SimpleChannelInboundHandler 
本项目中是extends ChannelInboundHandlerAdapter,但还是会出现IllegalReferenceCountException异常。
猜想有可能是发送命令时创建了ByteBuf,而引起的此异常,修改代码后问题解决。
posted @ 2020-06-29 11:44  枫露之茗  阅读(1408)  评论(0编辑  收藏  举报