JedisPool内存泄漏

时间:2017-03-07 09:33:56

标签: java spring-boot memory-leaks redis jedis

我在生产环境中使用jedisPool。当我启动服务器来处理请求时,redis池工作正常。但过了一会儿,日志文件就开始告诉我:'JedisException:无法从池中获取资源。'   这是我的配置:

redis.maxIdle=200
redis.minIdle=20
redis.maxWaitMillis=1000
redis.maxTotal=2000
redis.minEvictableIdleTimeMillis=300000

这是我的代码:

    public static String getStr(String key) {
    if (StringUtils.isEmpty(key))
        return null;

    JedisPool readPool = null;
    Jedis jedis = null;
    try {
        String redisKey = makeKey(key);
        readPool = getJedisPool();
        jedis = readPool.getResource();
        return jedis.get(redisKey);
    } catch (Exception ex) {
        log.warn("occurs exception", ex);
        throw ex;
    } finally {
        if (jedis != null && pool != null) {
        jedis.close();
    }
}

我很确定这个场景是由jedis实例内存泄漏引起的,因为日志文件继续记录相同的错误。我必须重新启动服务器才能停止它。   有没有人能告诉我内存泄漏发生在哪里?或者我错过了一些重要的配置?

1 个答案:

答案 0 :(得分:0)

constructor(props){ super(props); this.onClickEventHandler = this.onClickEventHandler.bind(this); this.onMouseEnterEventHandler= this.onMouseEnterEventHandler.bind(this); this.onMouseLeaveEventHandler= this.onMouseLeaveEventHandler.bind(this); } JedisPool都是Jedis,但您只关闭Closeable并且永远不会关闭池。这可能是导致你问题的原因。

假设你有Java 7或更高版本,试试这个:

Jedis

显然,上面会关闭池,所以如果你的池在几个消费者之间共享可能不是最好的主意,那么应该采取另一种方法。

根据Jedis消息来源,它在内部使用Apache的GeneridObjectPool。这些池要求客户在完成后将资源返回到池中,如在borrowObject的文档中捕获的那样:

  

按合同,客户必须使用ObjectPool.returnObject(T),ObjectPool.invalidateObject(T)或实现或子接口中定义的相关方法返回借用的实例。

在Jedis中,对String redisKey = makeKey(key); try (JedisPool readPool = getJedisPool(); Jedis jedis = readPool.getResource()) { return jedis.get(redisKey); } catch (Exception ex) { log.warn("occurs exception", ex); throw ex; } 方法的returnObject方法进行了类似的调用:

returnResourceObject(T)