java netty 内存泄露_Netty开发调试设置io.netty.leakDetection.level=PARANOID定位内存泄漏问题...
偶然一次再測試環境看到netty出現內存泄漏的日志,報錯信息如下:
LEAK: ByteBuf.release() was not called before it's garbage-collected. Enable advanced leak reporting to find out where the leak occurred. To enable advanced leak reporting, specify the JVM option '-Dio.netty.leakDetectionLevel=advanced' or call ResourceLeakDetector.setLevel()
看到這個錯誤,看不出內存泄漏的位置。但在環境里也沒有設置
-Dio.netty.leakDetectionLevel=advanced
這個問題在測試環境出現還好,如果在生產環境那就糟糕了。所以怎么可以今早在開發過程中就發現以及定位到內存泄漏的問題呢?
Netty的內存泄漏檢測分為四個級別:
DISABLED - 完成禁止檢測內存泄漏,這個是不推薦。
SIMPLE - 如果buffer中出現1%的內存泄漏,打印錯誤日志,就是上面那樣。但是日志是看不到詳細在什么位置出現了內存泄漏。鑒于性能考慮,這個是在生產環境中默認使用。
ADVANCED - 如果buffer的1%出現內存泄漏,打印錯誤,并且輸出詳細的內存泄漏信息。
PARANOID - 這個和ADVANCED輸出的內容是一樣的,但它會對每一次請求的buffer做檢查。很適用于調試和單元測試。
建議
1、為了今早的發現問題,強烈建議在開發調試過程中,把檢測級別設為PARANOID,設置:
io.netty.leakDetection.level=PARANOID
2、謹記哪里消費buffer,哪里釋放,即調用ReferenceCountUtil.release(msg)
public void channelRead(ChannelHandlerContext ctx, Object msg) {
try {
...
} finally {
ReferenceCountUtil.release(msg);
}
}
輸出的詳細信息示例
可以看出在EchoServerHandler上出現了內存泄漏。
12:05:24.374 [nioEventLoop-1-1] ERROR io.netty.util.ResourceLeakDetector - LEAK: ByteBuf.release() was not called before it's garbage-collected.
Recent access records: 2
#2:
Hint: 'EchoServerHandler#0' will handle the message from this point.
io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:329)
io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:846)
io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:133)
io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:485)
io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:452)
io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:346)
io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:794)
java.lang.Thread.run(Thread.java:744)
#1:
io.netty.buffer.AdvancedLeakAwareByteBuf.writeBytes(AdvancedLeakAwareByteBuf.java:589)
io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:208)
io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:125)
io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:485)
io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:452)
io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:346)
io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:794)
java.lang.Thread.run(Thread.java:744)
Created at:
io.netty.buffer.UnpooledByteBufAllocator.newDirectBuffer(UnpooledByteBufAllocator.java:55)
io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:155)
io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:146)
io.netty.buffer.AbstractByteBufAllocator.ioBuffer(AbstractByteBufAllocator.java:107)
io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:123)
io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:485)
io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:452)
io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:346)
io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:794)
java.lang.Thread.run(Thread.java:744)
總結
以上是生活随笔為你收集整理的java netty 内存泄露_Netty开发调试设置io.netty.leakDetection.level=PARANOID定位内存泄漏问题...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 快速突破流量瓶颈的方法,需从如下五点数据
- 下一篇: 格林函数(Green's functio