【问题标题】:netty 4 LEAK: ByteBuf was GC'd before being released correctlynetty 4 泄漏:ByteBuf 在被正确释放之前被 GC'd
【发布时间】:2016-06-18 19:34:15
【问题描述】:

我的 netty 服务器每天会收到一两次此警告,而解码方法每天处理超过 800 个数据包。

它似乎不喜欢的行是super.decode() 行,但我不确定是因为buffer 变量(本地变量)还是buf 变量(bytebuf我收到)。

我在finally 块中添加了release(),但警告仍然存在。

我使用的是 netty 4.0.4 final。

WARN  ResourceLeakDetector - LEAK: ByteBuf was GC'd before being released correctly.  The following stack trace shows where the leaked object was created, rather than where you failed to release it.
io.netty.util.ResourceLeakException: io.netty.buffer.UnpooledUnsafeDirectByteBuf@13e5013
    at io.netty.util.ResourceLeakDetector$DefaultResourceLeak.<init>(ResourceLeakDetector.java:174)
    at io.netty.util.ResourceLeakDetector.open(ResourceLeakDetector.java:116)
    at io.netty.buffer.UnpooledUnsafeDirectByteBuf.<init>(UnpooledUnsafeDirectByteBuf.java:72)
    at io.netty.buffer.UnpooledByteBufAllocator.newDirectBuffer(UnpooledByteBufAllocator.java:49)
    at io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:132)
    at io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:123)
    at io.netty.buffer.AbstractByteBufAllocator.buffer(AbstractByteBufAllocator.java:60)
    at io.netty.handler.codec.LengthFieldBasedFrameDecoder.extractFrame(LengthFieldBasedFrameDecoder.java:486)
    at io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:425)
    at PacketDecoder.decode(PacketDecoder.java:62)
    at io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:351)
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:231)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:131)
    at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:368)
    at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:353)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:780)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:100)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:497)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:465)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:359)
    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101)
    at java.lang.Thread.run(Thread.java:745)

我的代码:

@Override
protected Object decode(ChannelHandlerContext ctx, ByteBuf buf) throws Exception {
    LOGGER.info(" in the decode handler ");
    ByteBuf buffer = ((ByteBuf) super.decode(ctx, buf)).order(ByteOrder.BIG_ENDIAN);
    if (buffer == null) {
        LOGGER.error(" not all the message is received or a null message ");
        return null;
    }
    try {

        // reading the buffer until the end 
        // return something other than null     
        }

    }
    catch ( Exception e ){
        LOGGER.error(e.getMessage() );
        e.printStackTrace();
        return null;
    }
     finally {
         buffer.retain();
         buffer.release();
        }

}

【问题讨论】:

  • 为什么在finally块中调用`buffer.retain();`?
  • 因为 readindex 在我的 try 块结束时达到 0,所以我认为如果我错了,我不能直接调用 release 来纠正我。谢谢。
  • 你似乎对buffer.retain();的含义感到困惑,这增加了对象的内部引用计数,你只能在特殊情况下使用它。您可能只想在 finally 块中调用 buffer.release()
  • 谢谢,我不清楚

标签: java netty decoder


【解决方案1】:

您似乎并不总是调用 ByteBuf.release()。您应该确保始终释放缓冲区。

【讨论】:

  • 你的意思是在 catch 块中也调用 ByteBuf.release() 吗?谢谢
猜你喜欢
  • 1970-01-01
  • 2019-07-13
  • 1970-01-01
  • 2016-07-11
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 2011-12-17
相关资源
最近更新 更多