Java Netty中的ByteBuffers导致内存泄漏

Java Netty中的ByteBuffers导致内存泄漏,java,netty,Java,Netty,我创建了一个小型Netty服务器来计算BigInteger的阶乘并发送结果。代码如下 Factorial.java public class Factorial { private int port; public Factorial(int port) { this.port = port; } public void run(int threadcount) throws Exception { EventLoopGrou

我创建了一个小型Netty服务器来计算BigInteger的阶乘并发送结果。代码如下

Factorial.java

public class Factorial {

    private int port;

    public Factorial(int port) {
        this.port = port;
    }

    public void run(int threadcount) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup(threadcount);
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .childHandler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ch.pipeline().addLast(new FactorialHandler());
                 }
             })
             .option(ChannelOption.SO_BACKLOG, 128)          
             .childOption(ChannelOption.SO_KEEPALIVE, true); 

            ChannelFuture f = b.bind(port).sync(); 

            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        int port = 15000;
        new Factorial(port).run(Integer.parseInt(args[0]));
    }
}
当我运行这个时,我得到了以下错误

Jun 08, 2018 5:28:09 PM io.netty.util.ResourceLeakDetector reportTracedLeak
SEVERE: 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:
如给定链接中所述,我在
ctx.flush()
之后调用channelRead方法中的
buf.release()
来释放ByteBuffer

但当我这样做时,服务器开始抛出以下异常

io.netty.util.IllegalReferenceCountException: refCnt: 0, increment: 1

有人能告诉我如何解决这个问题吗?

这是因为你没有调用
msg.release()
(msg是ByteBuf的一个实例)。

问题不在于出站ByteBuf。出境旅客总是为您提供服务(请参阅)。问题在于入站的ByteBuf。我看着你,FactorialHandler。它延伸了。请注意JavaDoc中的这一点:

请注意,消息不会在 channelRead(ChannelHandlerContext,Object)方法返回 自动地如果您正在寻找ChannelInboundHandler 自动释放接收到的消息的实现, 请看

您的处理程序具有如下签名:

public void channelRead(ChannelHandlerContext ctx, Object msg)
这个msg(顺便说一下,您不使用它)实际上是一个ByteBuf,这正是上面JavaDoc注释警告您的。(在没有任何其他ChannelHandler的情况下,消息将始终是ByteBuf的实例。)

因此,您的选择是:

  • 使用SimpleChannelInboundHandler,它将为您清理该引用
  • 在处理程序结束时,使用释放入站ByteBuf

  • 也许这对您有所帮助,这里发布了
    objectmsg
    本身
    @Override public void channelRead(ChannelHandlerContext ctx,Object msg){//(2)//以静默方式放弃接收的数据。((ByteBuf)msg.release();//(3)}
    结果不是BigInteger类的实例吗?谢谢@Nicholas。添加ReferenceCountUtil.release(msg)修复了该问题
    public void channelRead(ChannelHandlerContext ctx, Object msg)