与弹性搜索中的Threadlocals存在内存泄漏相关的问题

时间:2014-11-23 15:32:24

标签: tomcat elasticsearch

我有一个Web服务,每次从UI按下按钮时,它都会连接到弹性搜索并触发查询。这是每次执行的代码。问题是,经过一段时间,间歇性地,UI挂起。

private static final String CONFIG_CLUSTER_NAME = "cluster.name";

private static final String CLUSTER_NAME = "sample_es";
private static final String[] transportAddress = {
    //Machine details
};

private static final int transportPort = 9300;

public static Client initClient(){
    settings = ImmutableSettings.settingsBuilder().put(CONFIG_CLUSTER_NAME, CLUSTER_NAME).build();

        Client client = new TransportClient(settings);
        for (int i=0 ; i < transportAddress.length-1 ; i++){
            ((TransportClient)client).addTransportAddress(new InetSocketTransportAddress(transportAddress[i], transportPort));
        }
        logger.info("TransportClient Created"); 
        return client;  
}


public static int query( String query) throws Exception
{
    Client client = null;
    try{

            client = initClient();

            //Query search code

    }catch(Exception e){
            e.printStackTrace();
    }finally{
        if(client != null){
            client.close();
            logger.info("TransportClient Closed");
        }
    }
        return result_count;
}

每当我们重新启动tomcat服务器时,这都是我们在日志中看到的错误消息。我们该如何解决这个问题?

[org.elasticsearch.common.util.concurrent.jsr166y.ThreadLocalRandom$1] (value
[org.elasticsearch.common.util.concurrent.jsr166y.ThreadLocalRandom$1@5838ce3e]) and a value of type
[org.elasticsearch.common.util.concurrent.jsr166y.ThreadLocalRandom] (value 
[org.elasticsearch.common.util.concurrent.jsr166y.ThreadLocalRandom@796c75b1]) but failed to remove it
when the web application was stopped. This is very likely to create a memory leak.

1 个答案:

答案 0 :(得分:1)

这不太可能是一个真正的问题,更多的是Elasticsearch没有使用Tomcat管理的线程池的问题。因此,每当您在运行查询后重新启动Tomcat时,很可能认为它会发现内存泄漏。这对于#34;非托管&#34;是常见的。在Tomcat中触发的线程。话虽如此,您可以通过运行探查器,然后监视线程和资源来验证自身是否清理。如果没有正确清理,那么我建议在Elasticsearch的GitHub存储库中创建一个问题。

关于您在创建客户端时所做的事情:我绝对建议您创建,使用,然后扔掉客户端。在启动时分配它,然后重用客户端,而不是根据需要不断重新创建它。然后在Tomcat想要停止时添加一个关闭钩子来关闭它。此外,for (int i=0 ; i < transportAddress.length-1 ; i++)正在跳过最后一个传输地址;使用i < transportAddress.length而不使用-1

不相关,但所有Elasticsearch Client的实现AutoCloseable(在Java 7中添加),这意味着如果您想继续这样做,可以简化代码以自动关闭

try (Client client = initClient()) {
    // Query search code
}
catch (Exception e) {
    logger.warning("An unexpected error occurred for the query: {}",
                   query, e);
}