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


背景、netty拋出完整的error信息如下:

2018-02-08 14:30:43.098 [nioEventLoopGroup-5-1] ERROR io.netty.util.ResourceLeakDetector:176 - 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.leakDetection.level=advanced' or call ResourceLeakDetector.setLevel() See http://netty.io/wiki/reference-counted-objects.html for more information.

一、結論很直觀:內存泄露了

再讀讀提示:獲取更多的信息有兩種方法

1. 增加啟動jvm參數-Dio.netty.leakDetection.level=advanced

java -jar -Dio.netty.leakDetection.level=advanced your-server.jar

或者

java -jar -Dio.netty.leakDetectionLevel=ADVANCED your-server.jar 

 

2. 在程序啟動時增加相關日志信息

...省略代碼...
try
{ ServerBootstrap sbs = new ServerBootstrap().group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class).handler(new LoggingHandler(LogLevel.INFO)) .localAddress(new InetSocketAddress(port)) .childHandler(new ChannelInitializer<SocketChannel>() { protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new IdleStateHandler(10, 0, 0, TimeUnit.SECONDS)); ch.pipeline().addLast(idleStateTrigger); ch.pipeline().addLast("decoder", new MessageDecoder()); ch.pipeline().addLast("encoder", new MessageEncoder()); ch.pipeline().addLast(serverHandler); }; }).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);
ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);
ChannelFuture future
= sbs.bind(port).sync();
...省略代碼...

 

二、這兩種方式都能跟蹤到內存泄露時的更多的拋出信息

Recent access records: 2
#2:
io.netty.buffer.AdvancedLeakAwareByteBuf.readBytes(AdvancedLeakAwareByteBuf.java:498)
io.netty.buffer.ByteBufInputStream.read(ByteBufInputStream.java:179)
com.esotericsoftware.kryo.io.Input.fill(Input.java:164)
com.esotericsoftware.kryo.io.Input.require(Input.java:196)
com.esotericsoftware.kryo.io.Input.readVarInt(Input.java:373)
com.esotericsoftware.kryo.util.DefaultClassResolver.readClass(DefaultClassResolver.java:127)
com.esotericsoftware.kryo.Kryo.readClass(Kryo.java:693)
com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:804)
com.your.package.base.serialize.KryoSerializer.deserialize(KryoSerializer.java:54)
com.your.package.base.link.MessageDecoder.decode(MessageDecoder.java:53)
io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(...)

 

三、解決問題

分析日志,建議從自己的代碼入手,然后將造成內存泄露的ByteBuf手動釋放。

ReferenceCountUtil.release(byteBuf);

 



免責聲明!

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



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