解决一系列tomcat热部署问题 create a memory leak.

开发环境中,一直使用热部署;

当重新编译的时候,有些资源不能够释放,从而占用了内存;多热部署几次就内存溢出了。

今天解决了这几个问题;

在实际项目中,主要是这几类资源无法释放:

1,连接池

2,自己写的任务队列线程,

3,mysql的线程;


爆出的warning大概是:

 [MySQL S tatement Cancellation Timer] but has failed to stop it. This is very likely to c reate a memory leak.


类似的问题应该是都是资源无法释放;


那我们就从这里入手:

1,释放连接池不能释放的资源:

    1)如果你用的是common-dbcp 可以参考这个:

         https://issues.apache.org/jira/browse/DBCP-332

    2)如果是连接池,可以开启一个context的监听器:

    

public class ContextDestroyedListener implements ServletContextListener {

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        System.out.println("you must be reload tomcat....please waiting ...");
          CacheManager.shutdown();
          Enumeration<Driver> drivers = DriverManager.getDrivers();
             while (drivers.hasMoreElements()) {
                 Driver driver = drivers.nextElement();
                 try {
                     DriverManager.deregisterDriver(driver);
                     System.out.println("stoping....  "+driver.toString());
                 } catch (SQLException e) {
                     e.printStackTrace();
                 }
             }
             Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
             Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]);
             for(Thread t:threadArray) {
                 if(t.getName().contains("Abandoned connection cleanup thread")||t.getName().contains("task_excutor")) {
                     synchronized(t) {
                         t.stop();
                     }
                 }
             }
    }

    @Override
    public void contextInitialized(ServletContextEvent arg0) {

    }

}


需要在web.xml里面配置监听。


还有需要特别注意的是:mysql驱动lib包尽量放在tomcat/lib下,因为这个驱动tomcat是可以共用的,当然,如果你只有一个应用,那就没有这个问题了。

参考:http://stackoverflow.com/questions/15632153/tomcat7-jdbc-datasource-this-is-very-likely-to-create-a-memory-leak


3)如果是自己的线程无法释放资源:

   我的处理器比较弱:

TaskExcutor te=new TaskExcutor();
Thread t = new Thread(te);
t.setName("task_excutor_thread_0");
t.start();

    可以使用线程名称来关闭:

  

if(t.getName().contains("Abandoned connection cleanup thread")||t.getName().contains("task_excutor")) {
                    synchronized(t) {
                        t.stop();
                    }
 }


可能你会遇到这个异常:

Exception in thread "task_excutor_thread_0" java.lang.IllegalMonitorStateExcepti
on
        at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLoc
k.java:155)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(Abstrac
tQueuedSynchronizer.java:1260)
        at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:46
0)
        at java.util.concurrent.LinkedBlockingDeque.takeFirst(LinkedBlockingDequ
e.java:492)
        at java.util.concurrent.LinkedBlockingDeque.take(LinkedBlockingDeque.jav
a:678)
        at com.cms.cache.TaskQueue.pull(TaskQueue.java:48)
        at com.cms.cache.TaskExcutor.run(TaskExcutor.java:8)
        at java.lang.Thread.run(Thread.java:745)

可能是应该没有用到线程锁的原因;具体原因是因为我没用到线程锁。



转载于:https://my.oschina.net/Tonyjingzhou/blog/514338

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值