2012-10-31 117 views
3

我正在运行使用Jedis访问Redis数据库的Tomcat应用程序。形成整个应用程序块的时间。通过使用JavaMelody监视Tomcat,我发现当对象请求Jedis实例时,问题似乎与JedisPool相关。Jedis正在耗尽资源实例,Web应用程序块

catalina-exec-74 
java.lang.Object.wait(Native Method) 
java.lang.Object.wait(Object.java:503) 
org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1104) 
redis.clients.util.Pool.getResource(Pool.java:20) 
.... 

这是我使用

JedisPoolConfig poolConfig = new JedisPoolConfig(); 
poolConfig.setMaxActive(20); 
poolConfig.setTestOnBorrow(true); 
poolConfig.setTestOnReturn(true); 
poolConfig.setMaxIdle(5); 
poolConfig.setMinIdle(5); 
poolConfig.setTestWhileIdle(true); 
poolConfig.setNumTestsPerEvictionRun(10); 
poolConfig.setTimeBetweenEvictionRunsMillis(10000); 
jedisPool = new JedisPool(poolConfig, "localhost"); 

的JedisPoolConfig所以,很显然有些线程试图获得一个Jedis实例,但该池是空的,所以默认池的行为是等待不能返回一个实例。

我已经仔细检查了我的整个代码,我很确定我将每个Jedis实例返回到之前使用的池中。所以我不确定为什么我会耗尽实例。

有没有办法来检查池中剩下多少实例?我试图为maxActive参数找到一个合理的值来防止应用程序被阻塞。

除了没有将Jedis实例返回到池之外,是否还有其他方法可以创建内存空洞?

+1

您是否设法解决此问题?我有完全相同的问题,正如你提到的,我很确定所有连接都返回了(我使用的是DAO模式,所以只有一个类使用Jedis)。提前致谢。 – pablochacin

回答

4

将资源返回池非常重要,所以请记住这样做。否则,当关闭你的应用程序时,它会等待资源返回。

https://groups.google.com/forum/?fromgroups=#!topic/jedis_redis/UeOhezUd1tQ

每个Jedis方法调用后,返回的资源池。您的应用程序可能已经使用了所有线程,并等待一些线程被删除。这可能会导致您正在解释的行为,并且该应用可能已被阻止。

Jedis jedis = JedisFactory.jedisPool.getResource(); 
try{ 
    jedis.set("key","val"); 
}finally{ 
    JedisFactory.jedisPool.returnResource(jedis); 
} 
2

部分答案,希望有一定的帮助的人在类似的情况下,虽然我不能确定我的问题是一样的你(如果你因为想通了已经,请告诉我们!) 。

我已经仔细检查了我的整个代码,我很确定我将每个Jedis实例返回到之前使用的池中。所以我不确定为什么我会耗尽实例。

我想我必须 - 我总是把我的代码中的try/finally块,但事实证明,我确实有内存泄漏:

Jedis jedis = DBHelper.pool.getResource(); 
    try { 
     // Next line causes the leak 
     Jedis jedis = DBHelper.pool.getResource(); 
     ... 
    } finally { 
     DBHelper.pool.returnResource(jedis); 
    } 

不知道第二次调用如何悄悄的,但它确实造成了漏洞和Web应用程序被阻止。

有没有办法来检查池中有多少实例?我试图为maxActive参数找到一个合理的值来防止应用程序被阻塞。

就我而言,我都发现了错误,并根据redis服务器看到的客户端数量进行了优化。我设置日志级别(在redis.confverbose(默认为notice),它将报告每5-10秒连接的客户端数量。一旦发现我的内存泄漏,我反复向请求调用该方法的页面发送请求,并且观看由redis日志爬升报告的redis客户端,但从不丢弃。。我认为这将是优化的良好开端?

无论如何,希望这对某人有帮助!

相关问题