3

Server version: Apache Tomcat/8.0.26
Server built: Aug 18 2015 11:38:37 UTC
Server number: 8.0.26.0
OS Name: Linux
OS Version: 2.6.32-642.3.1.el6.x86_64
Architecture: amd64
JVM Version: 1.8.0_60-b27
JVM Vendor: Oracle Corporation

I'm using jedis version : 2.8.2(commons-pool2:2.4.2) When I shutdown tomcat, there are some warning message.

13-Feb-2017 08:12:14.006 WARNING [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [ROOT] appears to have started a thread named [commons-pool-EvictionTimer] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
java.util.TimerThread.mainLoop(Timer.java:552)
java.util.TimerThread.run(Timer.java:505)

This is some conf of jedis.


...
@Bean(name = "jedisConnectionFactory", destroyMethod = "destroy")

public JedisConnectionFactory jedisConnectionFactory() throws IOException {
    final Properties redisConfig = PropertiesLoaderUtils.loadProperties(
                new PathMatchingResourcePatternResolver().getResource("classpath:redis.properties"));

    final JedisConnectionFactory result = new JedisConnectionFactory();
    result.setHostName(redisConfig.getProperty("redis.hostName"));
    result.setPort(Integer.parseInt(redisConfig.getProperty("redis.port")));
    result.setUsePool(Boolean.parseBoolean(redisConfig.getProperty("redis.pool.use")));
    result.setTimeout(Integer.parseInt(redisConfig.getProperty("redis.timeout")));
    result.setPoolConfig(createJedisPoolConfig(redisConfig));
    result.afterPropertiesSet();
    return result;
    }
...

How can i fix this?

cmk1105
  • 41
  • 1
  • 4
  • I faced a similar problem in the past. Problem back then were resources not being cleaned up correctly. We solved this by registering a `ServletContextListener`. – Julien Charon Feb 13 '17 at 08:51
  • Thank you for reply. I try to clean up in ServletContextListener by invoking jedisConnectionFactory.destroy(); Is there any way to clean up or registering? – cmk1105 Feb 13 '17 at 10:08

2 Answers2

0

Looks like a known problem, see https://github.com/xetorthio/jedis/issues/936.

Obviously, you don't need to cleanup the JedisConnectionFactory itself but the connection pool that was created with the help of the factory.

Julien Charon
  • 600
  • 1
  • 7
  • 21
0

The problem is that JedisConnectionFactory.afterPropertiesSet() is invoked twice, once in your code (result.afterPropsertiesSet()) and once by Spring. JedisConnectionFactory.afterPropsertiesSet() creates the Jedis connection pool which adds an eviction timer task to a ScheduledThreadPoolExecutor for each invocation. The JedisConnectionFactory keeps only the most recently created pool, so when it comes to cleaning up, only the last eviction timer task is cancelled but the others are not. This prevents the thread of the ScheduledThreadPoolExecutor from shutting down.

If you remove your call to result.afterPropertiesSet() then only one pool with one eviction task will be created and the thread will be shutdown once Spring destroys the JedisConnectionFactory.

Acanda
  • 672
  • 5
  • 12