Netty內存泄漏解決ERROR io.netty.util.ResourceLeakDetector - LEAK: ByteBuf.release() was not called before it's garbage-collected


最近用Netty框架開發網絡應用時,出現幾個異常報錯,仔細一看是內存泄漏了,提示ByteBuf對象在回收之前沒有調用ByteBuf.release()

ERROR io.netty.util.ResourceLeakDetector - LEAK: ByteBuf.release() was not called before it's garbage-collected

出現這個問題是因為程序中生成了池化的ByteBuf(PooledByteBuf)。PooledByteBuf的內存空間是從內存池中分配的,並且內部維持了一個計數器,用來記錄引用次數。PooledByteBuf在使用完之后要手動調用release()函數,該函數會減小引用次數,減小到0時就會將內存歸還在內存池中。如果不調用release()函數,JVM不知道引用計數的存在,釋放該對象時,可能還有其他引用在使用該內存空間,該內存空間也無法歸還到內存池中,從而導致內存泄漏。

關於ByteBuf內存泄漏更詳細的資料請移步Netty中ByteBuf內存泄露及釋放解析 

解決方法就是找到報錯的位置,找到生成的ByteBuf對象,在使用完之后調用對象的relesse()函數或者加上一句ReferenceCountUtil.release(msg)。如下面我出現的報錯

2020-06-12 17:04:41.242 [nioEventLoopGroup-2-1] ERROR io.netty.util.ResourceLeakDetector - LEAK: ByteBuf.release() was not called before it's garbage-collected. See https://netty.io/wiki/reference-counted-objects.html for more information.
Recent access records: 
Created at:
    io.netty.buffer.PooledByteBufAllocator.newDirectBuffer(PooledByteBufAllocator.java:363)
    io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:187)
    io.netty.buffer.AbstractByteBufAllocator.buffer(AbstractByteBufAllocator.java:123)
    io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:872)
    com.spring.netty.twg.service.TwgMessageDecoder.formatDecoder(TwgMessageDecoder.java:176)
    com.spring.netty.twg.service.TwgMessageDecoder.getMessageBody(TwgMessageDecoder.java:90)
    com.spring.netty.twg.service.TwgMessageDecoder.decode(TwgMessageDecoder.java:76)
    io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:332)
    io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:501)

在formatDecoder函數中,我調用readBytes()函數生成新ByteBuf對象byteBufChar。

在使用結束時,調用byteBufChar的release()函數  byteBufChar.release();

2020-06-12 17:04:45.460 [nioEventLoopGroup-2-1] ERROR io.netty.util.ResourceLeakDetector - LEAK: ByteBuf.release() was not called before it's garbage-collected. See https://netty.io/wiki/reference-counted-objects.html for more information.
Recent access records: 
Created at:
    io.netty.buffer.SimpleLeakAwareByteBuf.unwrappedDerived(SimpleLeakAwareByteBuf.java:143)
    io.netty.buffer.SimpleLeakAwareByteBuf.retainedSlice(SimpleLeakAwareByteBuf.java:57)
    io.netty.handler.codec.LengthFieldBasedFrameDecoder.extractFrame(LengthFieldBasedFrameDecoder.java:498)
    io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:437)
    com.spring.netty.twg.service.TwgMessageDecoder.decode(TwgMessageDecoder.java:31)
    io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:332)

在decode函數中,我調用了父類的decode()函數,生成新BytyBuf對象in,

在使用結束時,調用工具類,幫助回收in對象  ReferenceCountUtil.release(in)或者直接調用release()


免責聲明!

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



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