Я включил ResourceLeakDetector, но я получаю OutOfDirectMemoryError вместо ошибки утечки памяти Netty - PullRequest
0 голосов
/ 10 июля 2020

Пытаюсь проверить утечку памяти в версии netty: 4.1.50. Финал. Поскольку я не отпускаю ссылку в моем EchoServerInboundHandler. Итак, как я должен вызывать ошибку утечки памяти. УТЕЧКА: ByteBuf.release () не вызывался перед сборкой мусора. Включите расширенную отчетность об утечках, чтобы узнать, где произошла утечка. Чтобы включить расширенные отчеты об утечках, укажите параметр JVM '-Dio.netty.leakDetectionLevel = ADVANCED' или вызовите ResourceLeakDetector.setLevel ().

Echo client:

 @Sharable
    public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws InterruptedException {
    
            for (int i = 0; i < 10000000; i++) {
                System.out.println(i);
                ctx.writeAndFlush(Unpooled.copiedBuffer(i + "Netty rocks!", CharsetUtil.UTF_8));
    
            }
    
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            cause.printStackTrace();
            ctx.close();
        }
    
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
            // TODO Auto-generated method stub
    
        }
    }

Echo server

enter code here 
public void start() throws Exception {
    final EchoServerInboundHandler serverInHandler = new EchoServerInboundHandler();
    EventLoopGroup group = new NioEventLoopGroup();
    try {
        ServerBootstrap b = new ServerBootstrap();
        b.group(group).channel(NioServerSocketChannel.class).localAddress(new InetSocketAddress(port))
                .handler(new LoggingHandler(LogLevel.DEBUG)).childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(serverInHandler);
                    }
                }).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);
        ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.PARANOID);
        ChannelFuture f = b.bind().sync();
        System.out.println("Server running");
        System.out.println("VM parameter : ");
        ManagementFactory.getRuntimeMXBean().getInputArguments().forEach(System.out::println);
        System.out.println("ResourceLeakDetector level : " + ResourceLeakDetector.getLevel()
                + " ResourceLeakDetector isEnabled : " + ResourceLeakDetector.isEnabled());
        f.channel().closeFuture().sync();
    } finally {
        group.shutdownGracefully().sync();
    }
}

ChannelInboundHandlerAdapter

    @Sharable
public class EchoServerInboundHandler extends ChannelInboundHandlerAdapter {
    
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        System.out.println("EchoServerInboundHandler");
        ByteBuf b = Unpooled.copiedBuffer((ByteBuf) msg);
        System.out.println("Server received: " + b.toString(CharsetUtil.UTF_8));
//      ReferenceCountUtil.release(msg);
    }
     
       @Override
        @SuppressWarnings("deprecation")
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
                throws Exception {
            ctx.fireExceptionCaught(cause);
        }

    
}

Завершить вывод:

Jul 10, 2020 10:02:23 PM io.netty.handler.logging.LoggingHandler channelRegistered
SEVERE: [id: 0x6818efa3] REGISTERED
Jul 10, 2020 10:02:23 PM io.netty.handler.logging.LoggingHandler bind
SEVERE: [id: 0x6818efa3] BIND: 0.0.0.0/0.0.0.0:8081
Server running
VM parameter : 
Jul 10, 2020 10:02:23 PM io.netty.handler.logging.LoggingHandler channelActive
SEVERE: [id: 0x6818efa3, L:/0:0:0:0:0:0:0:0:8081] ACTIVE
-agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:52462
-Xmx5m
-Dio.netty.leakDetection.level=PARANOID
-Dfile.encoding=UTF-8
ResourceLeakDetector level : PARANOID ResourceLeakDetector isEnabled : true


Jul 10, 2020 9:31:37 PM io.netty.channel.DefaultChannelPipeline onUnhandledInboundException
WARNING: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
io.netty.util.internal.OutOfDirectMemoryError: failed to allocate 384 byte(s) of direct memory (used: 5766864, max: 5767168)
    at io.netty.util.internal.PlatformDependent.incrementMemoryCounter(PlatformDependent.java:754)
    at io.netty.util.internal.PlatformDependent.allocateDirectNoCleaner(PlatformDependent.java:709)
    at io.netty.buffer.UnpooledUnsafeNoCleanerDirectByteBuf.allocateDirect(UnpooledUnsafeNoCleanerDirectByteBuf.java:30)
    at io.netty.buffer.UnpooledDirectByteBuf.<init>(UnpooledDirectByteBuf.java:64)
    at io.netty.buffer.UnpooledUnsafeDirectByteBuf.<init>(UnpooledUnsafeDirectByteBuf.java:41)
    at io.netty.buffer.UnpooledUnsafeNoCleanerDirectByteBuf.<init>(UnpooledUnsafeNoCleanerDirectByteBuf.java:25)
    at io.netty.buffer.UnsafeByteBufUtil.newUnsafeDirectByteBuf(UnsafeByteBufUtil.java:625)
    at io.netty.buffer.PooledByteBufAllocator.newDirectBuffer(PooledByteBufAllocator.java:359)
    at io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:187)
    at io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:178)
    at io.netty.buffer.AbstractByteBufAllocator.ioBuffer(AbstractByteBufAllocator.java:139)
    at io.netty.channel.DefaultMaxMessagesRecvByteBufAllocator$MaxMessageHandle.allocate(DefaultMaxMessagesRecvByteBufAllocator.java:114)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:147)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.lang.Thread.run(Thread.java:745)
...