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,而引起的此異常,修改代碼后問題解決。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM