zoukankan      html  css  js  c++  java
  • 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);


  • 相关阅读:
    ssh
    步进器&分栏控制器
    一些过期的整理前端代码
    进度条和滑动条
    UISwitcher
    定时器
    创建window
    iOS开发---UIButton 1 //创建一个可以显示图片的按钮。
    iOS开发---UILabel
    今日头条前端编程题
  • 原文地址:https://www.cnblogs.com/yoyotl/p/8433135.html
Copyright © 2011-2022 走看看