美文网首页
Netty的一个容易造成内存溢出的一个坑

Netty的一个容易造成内存溢出的一个坑

作者: cocalrush | 来源:发表于2017-09-17 22:41 被阅读0次

    昨天解决了队列过大导致内存溢出的一个问题,今天起床再看下程序,发现程序其他线程均停止了,只有一个monitor线程再不断打出监控数据。可以看到队列的问题不存在了!因为队列根本没数据!!但是其他线程还是hang住了!

    用jmap 打印出堆栈信息发行当前内存使用也是正常的,没有被占完。这就百思不得其解了。后面猛然想到,偶然在哪看过一篇文章netty好像有一步需要手动释放内存的。= = 去搜索了下果然...

    netty的ByteBuff如果是自己分配的,没有提交给netty write的需要手动释放!

      ReferenceCountUtil.release(byteBuf);
    

    netty设计者早就考虑到了这个坑所以会抽样一部分的ByteBuff 并且打出警告日志
    提醒你某个地方的ByteBuff忘记释放了。但是这个报错还是只打一次。还是得加了这个

     ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);
    

    的情况下才会打出堆栈信息 - -。 所以这个错误就被埋葬在茫茫多的调试信息里面了。
    自己申请的ByteBuff需要手动释放,大概看了下还是没搞太懂。先记录下,后面有空再仔细看下!

    报错如下 LEAK: ByteBuf.release()  !!!!⚠️这个报错:
    2017-09-17 22:33:40.525 ERROR 15973 --- [ntLoopGroup-2-1] io.netty.util.ResourceLeakDetector       : LEAK: ByteBuf.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.
    Recent access records: 1
    #1:
        io.netty.buffer.AdvancedLeakAwareByteBuf.readBytes(AdvancedLeakAwareByteBuf.java:492)
        com.cocal.Handle.FakeDhtHandle.channelRead0(FakeDhtHandle.java:59)
        com.cocal.Handle.FakeDhtHandle.channelRead0(FakeDhtHandle.java:35)
        io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
        io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1359)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
        io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:935)
        io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read(AbstractNioMessageChannel.java:93)
        io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
        io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
        io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
        io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
        io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
        io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
        java.lang.Thread.run(Thread.java:745)
    Created at:
        io.netty.util.ResourceLeakDetector.track(ResourceLeakDetector.java:237)
        io.netty.buffer.PooledByteBufAllocator.newDirectBuffer(PooledByteBufAllocator.java:331)
        io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:181)
        io.netty.buffer.UnsafeByteBufUtil.copy(UnsafeByteBufUtil.java:436)
        io.netty.buffer.PooledUnsafeDirectByteBuf.copy(PooledUnsafeDirectByteBuf.java:309)
        io.netty.buffer.AbstractByteBuf.copy(AbstractByteBuf.java:1168)
        io.netty.channel.socket.DatagramPacket.copy(DatagramPacket.java:47)
        com.cocal.Handle.FakeDhtHandle.channelRead0(FakeDhtHandle.java:56)
        com.cocal.Handle.FakeDhtHandle.channelRead0(FakeDhtHandle.java:35)
        io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
        io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
        io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1359)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
        io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
        io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:935)
        io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read(AbstractNioMessageChannel.java:93)
        io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
        io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
        io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
        io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
        io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
        io.netty.util.concurrent.DefaultThreadFactory$Default
    

    这个提示我这个地方的ByteBuff没有释放
    com.cocal.Handle.FakeDhtHandle.channelRead0(FakeDhtHandle.java:56)

    相关文章

      网友评论

          本文标题:Netty的一个容易造成内存溢出的一个坑

          本文链接:https://www.haomeiwen.com/subject/xmxscxtx.html