2012-10-31 45 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客戶端,但從不丟棄。。我認爲這將是優化的良好開端?

無論如何,希望這對某人有幫助!

相關問題