代码之家  ›  专栏  ›  技术社区  ›  Tiina

HTTP服务器的Netty内存泄漏。何时发布消息?

  •  1
  • Tiina  · 技术社区  · 6 年前

    除非使用 SimpleChannelInboundHandler channelRead0 ,如果 ctx.fireChannelRead 未调用。

    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        log.error("receive {}", msg);
        if (msg instanceof FullHttpRequest) {            
            FullHttpRequest req = (FullHttpRequest) msg;
            ReferenceCountUtil.release(msg);
            clientChannel.writeAndFlush(new RequestWrapper(req, foo)); 
        }
    }
    

    clientChannel.writeAndFlush 成功时,推动 requestWrapper 排队。荨麻不显示 LEAK warnings ,但如中所述 jvm out of memory ,此项目的旧一代增加,事件 ReferenceCountUtil.release(msg) .

    1. 如果没有释放HTTP输入消息,为什么 official example 不显式调用release吗?
    2. 在里面 channelRead ,如果在另一个bean中设置了接收到的msg,则该bean由 CTX.消防通道读取 ,我应该为这个消息调用release吗,如上面的代码?
    3. 如果传递了一个新对象 ctx.fireChannelRead(newObject) ,我应该打电话吗 release(newObject) 在下一个处理程序中?

    这样地:

    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ctx.fireChannelRead("hello world");
    }
    
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        assert "hello world".equals(msg);
        ReferenceCountUtil.release(msg); // is this necessary if it is created in the former handler?
    }
    
    1. 写操作怎么样,我还应该为写对象调用release吗?

    这样地:

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        ctx.write("bye", promise);
    }
    
    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        assert "bye".equals(msg);
        // should I call ReferenceCountUtil.release(msg); ?
        ctx.write(“bye bye”, promise);
    }
    
    2 回复  |  直到 6 年前
        1
  •  3
  •   senninha    6 年前

        public static boolean release(Object msg) {
        if (msg instanceof ReferenceCounted) {
            return ((ReferenceCounted) msg).release();
        }
        return false;
    }
    

        2
  •  1
  •   Tiina    6 年前

    ReferenceCountUtil.refCnt

    public static int refCnt(Object msg) {
        return msg instanceof ReferenceCounted ? ((ReferenceCounted) msg).refCnt() : -1;
    }
    

    write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        FullHttpResponse fullHttpResponse = ...
        ctx.write(fullHttpResponse, promise);
    }
    

    FullHttpResponse ByteBuffer.allocate

    userFiredEvents

        ctx.write(msg, promise);
        ctx.flush();