在用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,而引起的此异常,修改代码后问题解决。
