Memory leaks 干净地关闭Netty服务器

Memory leaks 干净地关闭Netty服务器,memory-leaks,netty,shutdown,jboss-arquillian,Memory Leaks,Netty,Shutdown,Jboss Arquillian,您好,目前我正在为Moco框架()开发一个Arquillian扩展。Moco用于测试RESTful服务,并依赖Netty处理通信。目前Moco正在使用Netty 4.0.18.Final 但我发现在容器内运行Moco(和Netty server)时(Arquillian在容器内运行测试)存在一个问题,即它正确启动,但当应用程序取消部署且服务器关闭时,会打印下一个日志错误消息: 严重:web应用程序[/ba32e781-3a18-44b3-9547-7c26787f3fe7]似乎已启动名为[poo

您好,目前我正在为Moco框架()开发一个Arquillian扩展。Moco用于测试RESTful服务,并依赖Netty处理通信。目前Moco正在使用Netty 4.0.18.Final

但我发现在容器内运行Moco(和Netty server)时(Arquillian在容器内运行测试)存在一个问题,即它正确启动,但当应用程序取消部署且服务器关闭时,会打印下一个日志错误消息:

严重:web应用程序[/ba32e781-3a18-44b3-9547-7c26787f3fe7]似乎已启动名为[pool-2-thread-1]的线程,但未能停止该线程。这很可能会造成内存泄漏。 abr 082014 10:29:06 AM org.apache.catalina.loader.WebappClassLoader检查线程LocalMapForLeaks 严重:web应用程序[/ba32e781-3a18-44b3-9547-7c26787f3fe7]使用类型为[io.netty.util.internal.ThreadLocalRandom$2](值[io.netty.util.internal.ThreadLocalRandom]的键创建了ThreadLocal$2@77468cae])以及类型为[io.netty.util.internal.ThreadLocalRandom](值[io.netty.util.internal)的值。ThreadLocalRandom@6cd3851])但在web应用程序停止时无法删除它。线程将随着时间的推移而更新,以尝试避免可能的内存泄漏

基本上,当服务器试图关闭时,有些线程似乎还没有关闭

从Arquillian扩展的角度来看,当应用程序部署到服务器时,调用Moco的start方法,在取消部署应用程序之前,调用Moco的stop方法

但让我向您展示Moco的代码:

public int start(final int port, ChannelHandler pipelineFactory) {
    ServerBootstrap bootstrap = new ServerBootstrap();
    bootstrap.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .childHandler(pipelineFactory);

    try {
        future = bootstrap.bind(port).sync();
        SocketAddress socketAddress = future.channel().localAddress();
        address = (InetSocketAddress) socketAddress;
        return address.getPort();
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
停止方法如下所示:

private void doStop() {
    if (future != null) {
        future.channel().close().syncUninterruptibly();
        future = null;
    }
因此,close方法似乎在杀死所有线程之前返回,因此容器会警告您可能的内存泄漏

因为我从未使用过Netty,我想知道是否有办法确保整个Netty运行时都关闭

非常感谢您的帮助。

我对Netty也是新手(也不熟悉Arquillian),但根据Netty Docs的示例,我相信您可能不会关闭您创建的
EventLoopGroup
s(bossGroup,workerGroup)。从:

关闭Netty应用程序通常与关闭通过shutdownGracefully()创建的所有EventLoopGroup一样简单。它返回一个Future,当EventLoopGroup完全终止并且属于该组的所有通道都已关闭时,它会通知您

因此,您的doStop()方法可能如下所示:

private void doStop() {
    workerGroup.shutdownGracefully();
    bossGroup.shutdownGracefully();
}
Netty文档中的一个示例: