1. 问题:日志中出现下面的警告:

警告: The web application [ROOT] appears to have started a thread named [HouseKeeper] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Thread.sleep(Native Method)
org.logicalcobwebs.proxool.HouseKeeperThread.run(HouseKeeperThread.java:46)

2. 原因调查:

使用的是 proxool 连接池,查看源码,分析如下:

在项目某种情况下,ProxoolFacade.shutdown(); 被调用,他会调用:

    protected static void shutdown(String finalizer, int delay) {

        ConnectionPool[] cps = ConnectionPoolManager.getInstance().getConnectionPools();
for (int i = 0; i < cps.length; i++) {
removeConnectionPool(finalizer, cps[i], delay);
} // If a shutdown hook was registered then remove it
try {
if (shutdownHook != null) {
ShutdownHook.remove(shutdownHook);
}
} catch (Throwable t) {
if (LOG.isDebugEnabled()) {
LOG.debug("Unanticipated error during removal of ShutdownHook. Ignoring it.", t);
}
} // Stop threads
PrototyperController.shutdown();
HouseKeeperController.shutdown(); }

这里 首先 关闭连接池,然后在最后面关闭了一个 housekeeper 的 demaon线程:

 HouseKeeperController.shutdown();
    /**
* Stop all house keeper threads.
*/
protected static void shutdown() {
synchronized(LOCK) {
Iterator i = houseKeeperThreads.iterator();
while (i.hasNext()) {
HouseKeeperThread hkt = (HouseKeeperThread) i.next();
LOG.info("Stopping " + hkt.getName() + " thread");
hkt.cancel();
}
houseKeeperThreads.clear();
}
}

对每一个 housekeeper 线程调用 cancel() 方法,一般只有一个 housekeeper线程:

hkt.cancel();
public class HouseKeeperThread extends Thread {
private static final Log LOG = LogFactory.getLog(HouseKeeperThread.class);
private boolean stop;
public HouseKeeperThread(String name) {
setDaemon(true);
setName(name);
}
public void run() {
while (!stop) {
HouseKeeper hk = HouseKeeperController.getHouseKeeperToRun();
while (hk != null && !stop) {
try {
// if (LOG.isDebugEnabled()) {
// LOG.debug("About to sweep " + hk.getAlias());
// }
hk.sweep();
} catch (ProxoolException e) {
LOG.error("Couldn't sweep " + hk.getAlias(), e);
}
hk = HouseKeeperController.getHouseKeeperToRun();
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
LOG.error("Interrupted", e);
}
}
}
protected void cancel() {
stop = true;
}
}

尼玛 stop 尽然是一个 普通 的 boolean 变量,感觉应该使用 volatile 修饰!

保错的原因是,housekeeper 线程因为每隔5秒执行一次,而系统 想要 stop 它的时候,它正在 sleep ,所以抛出了异常:

警告: The web application [ROOT] appears to have started a thread named [HouseKeeper] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Thread.sleep(Native Method)
org.logicalcobwebs.proxool.HouseKeeperThread.run(HouseKeeperThread.java:46)

但是,因为 设置了 stop = true,所以,当它 sleep 完成之后,也可能会 判断 stop == true, 也可能判断 stop == false,因为这里没有使用 volatile 修饰!

所以最坏的结果,就是 有一个名叫 "HouseKeeper" 的 deamon jvm 线程没有被成功关闭。

3. 日志显示,数据库连接池,确实被正确关闭了:

ContainerBackgroundProcessor[StandardEngine[Catalina]] - Proxool shoutdown
[INFO ] org.logicalcobwebs.proxool.ConnectionPool.shutdown(ConnectionPool.java:484):ContainerBackgroundProcessor[StandardEngine[Catalina]] - Shutting down 'autumn' pool immediately [ContainerBackgroundProcessor[StandardEngine[Catalina]]]
[DEBUG] org.logicalcobwebs.proxool.ConnectionPool.removeProxyConnection(ConnectionPool.java:441):ContainerBackgroundProcessor[StandardEngine[Catalina]] - 000003 (00/05/00) - #0006 removed because of shutdown.
[DEBUG] org.logicalcobwebs.proxool.ConnectionPool.shutdown(ConnectionPool.java:547):ContainerBackgroundProcessor[StandardEngine[Catalina]] - Connection #6 closed
[DEBUG] org.logicalcobwebs.proxool.ConnectionPool.removeProxyConnection(ConnectionPool.java:441):ContainerBackgroundProcessor[StandardEngine[Catalina]] - 000003 (00/04/00) - #0005 removed because of shutdown.
[DEBUG] org.logicalcobwebs.proxool.ConnectionPool.shutdown(ConnectionPool.java:547):ContainerBackgroundProcessor[StandardEngine[Catalina]] - Connection #5 closed
[DEBUG] org.logicalcobwebs.proxool.ConnectionPool.removeProxyConnection(ConnectionPool.java:441):ContainerBackgroundProcessor[StandardEngine[Catalina]] - 000003 (00/03/00) - #0004 removed because of shutdown.
[DEBUG] org.logicalcobwebs.proxool.ConnectionPool.shutdown(ConnectionPool.java:547):ContainerBackgroundProcessor[StandardEngine[Catalina]] - Connection #4 closed
[DEBUG] org.logicalcobwebs.proxool.ConnectionPool.removeProxyConnection(ConnectionPool.java:441):ContainerBackgroundProcessor[StandardEngine[Catalina]] - 000003 (00/02/00) - #0003 removed because of shutdown.
[DEBUG] org.logicalcobwebs.proxool.ConnectionPool.shutdown(ConnectionPool.java:547):ContainerBackgroundProcessor[StandardEngine[Catalina]] - Connection #3 closed
[DEBUG] org.logicalcobwebs.proxool.ConnectionPool.removeProxyConnection(ConnectionPool.java:441):ContainerBackgroundProcessor[StandardEngine[Catalina]] - 000003 (00/01/00) - #0002 removed because of shutdown.
[DEBUG] org.logicalcobwebs.proxool.ConnectionPool.shutdown(ConnectionPool.java:547):ContainerBackgroundProcessor[StandardEngine[Catalina]] - Connection #2 closed
[DEBUG] org.logicalcobwebs.proxool.ConnectionPool.removeProxyConnection(ConnectionPool.java:441):ContainerBackgroundProcessor[StandardEngine[Catalina]] - 000003 (00/00/00) - #0001 removed because of shutdown.
[DEBUG] org.logicalcobwebs.proxool.ConnectionPool.shutdown(ConnectionPool.java:547):ContainerBackgroundProcessor[StandardEngine[Catalina]] - Connection #1 closed
[INFO ] org.logicalcobwebs.proxool.ConnectionPool.shutdown(ConnectionPool.java:564):ContainerBackgroundProcessor[StandardEngine[Catalina]] - 'autumn' pool has been closed down by ContainerBackgroundProcessor[StandardEngine[Catalina]] in 6 milliseconds.
[DEBUG] org.logicalcobwebs.proxool.ShutdownHook.remove(ShutdownHook.java:41):ContainerBackgroundProcessor[StandardEngine[Catalina]] - Removed shutdownHook
[INFO ] org.logicalcobwebs.proxool.PrototyperController.shutdown(PrototyperController.java:100):ContainerBackgroundProcessor[StandardEngine[Catalina]] - Stopping Prototyper thread
[INFO ] org.logicalcobwebs.proxool.HouseKeeperController.shutdown(HouseKeeperController.java:107):ContainerBackgroundProcessor[StandardEngine[Catalina]] - Stopping HouseKeeper thread

排除了 poxool 导致 数据库连接泄露的问题。

proxool 连接池警告分析:appears to have started a thread named [HouseKeeper] but has failed to stop it的更多相关文章

  1. 警告: The web application [ROOT] appears to have started a thread named [Thread-48] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:

    1. 问题描述 tomcat跑web项目(其中依赖java项目) 出现大量上述警告 项目起不来 关键字 memory leak 内存泄漏 2. 解决方案 难道是程序写的有问题? 最终 将tomcat ...

  2. 严重:The web application [web01] appears to have started a thread named ...

    Tomcat报错 严重:The web application [web01] appears to have started a thread named [PooledThread-1] but ...

  3. paip.proxool连接池 :Attempt to refer to a unregistered pool by its alias 'xx'

    paip.proxool连接池 :Attempt to refer to a unregistered pool by its alias 'xx' 作者Attilax  艾龙,  EMAIL:146 ...

  4. 使用proxool 连接池:No suitable driver found for proxool

    使用proxool连接池时:报错误No suitable driver found for proxool.shide的原因: ①.WEB-INF目录下的lib中没有proxool连接池jar驱动包. ...

  5. 使用proxool连接池配置教程

    proxool连接池的优点: 1.透明度:透明地将连接池添加到现有的JDBC驱动程序. 2.开源:我们的许可证允许您灵活地将其用于商业和其他开源产品. 3.标准:符合J2SE API,使您有信心开发标 ...

  6. MySql 8小时解决方案:proxool连接池

    最近做的项目用的mysql数据库,前天挂在服务器上,昨天早晨上班一来,同事就说API数据接口访问不了了,我马上mstsc登陆服务器看,报错了.马上重启tomcat,结果还能正常运行,当时没管,今天过来 ...

  7. Spring学习11-Spring使用proxool连接池 管理数据源

    Spring 一.Proxool连接池简介及其配置属性概述   Proxool是一种Java数据库连接池技术.是sourceforge下的一个开源项目,这个项目提供一个健壮.易用的连接池,最为关键的是 ...

  8. proxool 连接池

    今天配置proxool 连接池,发现可配置属性非常多,以前也只是用,没总结过,今天查了下网上的资料,总结一下 方便你我.其实网上很多英文资料都很全,网上很多人就是考翻译老外的文章赚些流量,其实也没啥意 ...

  9. proxool连接池参数解释

        数据库连接池概述: 数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出.对数据库连接的管理能显著影响到整个 应用程序的伸缩性和健壮性,影响到程序的性能指标.数 ...

随机推荐

  1. 【Java每日一题】20161116

    package Nov2016; public class Ques1116 { public static void main(String[] args){ System.out.println( ...

  2. MVC-自定义过滤器

    APS.NET MVC中的每一个请求,都会分配给相应的控制器和对应的行为方法去处理,而在这些处理的前前后后如果想再加一些额外的逻辑处理.这时候就用到了过滤器. 自定义过滤器: 若要自定义一个过滤器,则 ...

  3. Spring发展历程总结

    目前很多公司的架构,从Struts2迁移到了SpringMVC.你有想过为什么不使用Servlet+JSP来构建Java web项目,而是采用SpringMVC呢? 既然这样,我们从源头说起.Stru ...

  4. 框架SpringMVC笔记系列 一 基础

    主题:SpringMVC 学习资料参考网址: 1.http://www.icoolxue.com 2.http://aokunsang.iteye.com/blog/1279322 1.SpringM ...

  5. php中数组遍历改值

    <?php $arr = array(100, 99, 88, 77, 55, 66); //方法1 foreach ($arr as &$v) { $v = 2; } print_r( ...

  6. Java集合源码分析(五)HashSet<E>

    HashSet简介 HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持.它不保证set 的迭代顺序:特别是它不保证该顺序恒久不变.此类允许使用null元素. HashSet源 ...

  7. 使用Apache的DigestUtils类实现哈希摘要(SHA/MD5)

    包名称:org.apache.commons.codec.digest 类名称:org.apache.commons.codec.digest.DigestUtils 1.MD5 public sta ...

  8. 跨平台日志清理工具 Log-Cutter v2.0.1 RC-1 发布

    Log-Cutter 是JessMA开源组织开发的一个简单实用的日志切割清理工具.对于服务器的日常维护来说,日志清理是非常重要的事情,如果残留日志过多则严重浪费磁盘空间同时影响服务的性能.如果用手工方 ...

  9. java 基础加强--书籍+题目+上机测试

    scjp test( 在线测试网站):http://scjptest.com/mock-test.xhtml <SCJP Sun® Certified Programmer for Java™ ...

  10. Servlet过滤器Filter用法

    1 Servlet 过滤器方法 过滤器是一个实现了 javax.servlet.Filter 接口的 Java 类.javax.servlet.Filter 接口定义了三个方法:public void ...