首页  

netty ByteBuf 泄露实例     所属分类 netty 浏览量 1485
以 discard 例子为例

DiscardServerHandler 继承  SimpleChannelInboundHandler
实现 channelRead0 方法
在 SimpleChannelInboundHandler 的  channelRead 里会做 释放
因此官方的例子没有问题

DIY一个 没有释放 造成泄露的  MyDiscardServerHandler

注意   MyDiscardServerHandler 继承 ChannelInboundHandlerAdapter !!!

public class MyDiscardServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // discard
    	// 没有release  堆外内存会溢出
    	// java.lang.OutOfMemoryError: Direct buffer memory
    	// System.out.println(msg.toString());
    	System.out.println(DiscardServer.getInfo(msg));
    	
    	// System.gc();

    }

DiscardServer 增加启动参数 
-Dio.netty.leakDetectionLevel=advanced

启动 DiscardClient 不断的往 DiscardServer 发数据
DiscardClient  是一个 基于 BIO 用 socket 实现的 客户端

完整代码
https://gitee.com/dyyx/netty4demo/tree/master/src/main/java/dyyx/discard

观察 DiscardServer 日志  ,会发现 LEAK 信息

LEAK: ByteBuf.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.

cat xxx.log |grep LEAK: | wc -l

ERROR nioEventLoopGroup-3-1 io.netty.util.ResourceLeakDetector io.netty.util.ResourceLeakDetector.reportTracedLeak(ResourceLeakDetector.java:311) - 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:
	io.netty.buffer.AdvancedLeakAwareByteBuf.getBytes(AdvancedLeakAwareByteBuf.java:244)
	dyyx.util.CommUtil.toString(CommUtil.java:27)
	dyyx.discard.DiscardServer.getInfo(DiscardServer.java:64)
	dyyx.discard.MyDiscardServerHandler.channelRead(MyDiscardServerHandler.java:17)
	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:1434)
	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
	io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
	io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:644)
	io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:579)
	io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:496)
	io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:458)
	io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:897)
	io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	java.lang.Thread.run(Thread.java:745)
#2:
	Hint: 'MyDiscardServerHandler#0' will handle the message from this point.
	io.netty.channel.DefaultChannelPipeline.touch(DefaultChannelPipeline.java:116)
	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)
	io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
	io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
	io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:644)
	io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:579)
	io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:496)
	io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:458)
	io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:897)
	io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	java.lang.Thread.run(Thread.java:745)
#3:
	Hint: 'DefaultChannelPipeline$HeadContext#0' will handle the message from this point.
	io.netty.channel.DefaultChannelPipeline.touch(DefaultChannelPipeline.java:116)
	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:345)
	io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
	io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
	io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:644)
	io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:579)
	io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:496)
	io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:458)
	io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:897)
	io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	java.lang.Thread.run(Thread.java:745)
#4:
	io.netty.buffer.AdvancedLeakAwareByteBuf.writeBytes(AdvancedLeakAwareByteBuf.java:634)
	io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:347)
	io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:148)
	io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:644)
	io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:579)
	io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:496)
	io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:458)
	io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:897)
	io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	java.lang.Thread.run(Thread.java:745)
Created at:
	io.netty.buffer.PooledByteBufAllocator.newDirectBuffer(PooledByteBufAllocator.java:331)
	io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:185)
	io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:176)
	io.netty.buffer.AbstractByteBufAllocator.ioBuffer(AbstractByteBufAllocator.java:137)
	io.netty.channel.DefaultMaxMessagesRecvByteBufAllocator$MaxMessageHandle.allocate(DefaultMaxMessagesRecvByteBufAllocator.java:114)
	io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:147)
	io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:644)
	io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:579)
	io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:496)
	io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:458)
	io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:897)
	io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	java.lang.Thread.run(Thread.java:745)

上一篇     下一篇
netty ByteBuf 释放说明

eclipse使用用技巧

netty ByteBuf 实战

netty使用技巧

vert.x介绍

基于netty实例演示NIO BIO 异步和同步