Tomcat 6内存泄漏日志条目

下面是我在CentOS机器上的Catalina.out文件中输入的唯一条目。 我正在使用Spring 3和我的应用程序运行Tomcat 6。 有很多这样的,所以我选择了一些不断重复的东西。 这不会一直发生,但每周至少发生一次。

问题是我该如何防止波纹发生?

Feb 3, 2011 2:37:48 PM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc SEVERE: The web application [] registered the JBDC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered. Feb 3, 2011 2:37:48 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads SEVERE: The web application [] appears to have started a thread named [com.iteezy.shared.domain.DirEntry.data] but has failed to stop it. This is very likely to create a memory leak. Feb 3, 2011 2:37:48 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads SEVERE: The web application [] appears to have started a thread named [com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0] but has failed to stop it. This is very likely to create a memory leak. Feb 3, 2011 2:37:48 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads SEVERE: The web application [] appears to have started a thread named [File Reaper] but has failed to stop it. This is very likely to create a memory leak. Feb 3, 2011 2:37:48 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads SEVERE: The web application [] appears to have started a thread named [pool-1-thread-22] but has failed to stop it. This is very likely to create a memory leak. 37:48 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads b application [] appears to have started a thread named [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2] but has failed to stop it. This is very likely to create a memory leak. 37:48 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap b application [] created a ThreadLocal with key of type [net.sf.json.AbstractJSON$1] (value [net.sf.json.AbstractJSON$1@40bbb3d6]) and a value of type [java.util.HashSet] (value [[]]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak. 

当你定义一个线程被假定为轮询的外部标志并在它被设置时退出时 – 它必须是volatile 。 否则,线程可能永远不会看到其他线程所做的更改。

但是在标准API中已经存在类似的function – 它被称为interrupt()方法和Thread.currentThread().isInterrupted() 。 无需复制已有的逻辑。 请参阅: 停止特定的Java线程 。

也就是说,在每个线程上调用interrupt()也是一个坏主意,因为不能保证所有线程都响应它。 检查您的exception我注意到以下线程未正确清理:

  • com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0 – 关闭C3P0数据源。 因为你使用Spring只需添加destroy-method="close" 。 我们完成了这个主题。

  • File Reaper – 据我所知,这个post是由FileCleaningTracker创建的。 在关闭应用程序时(或者当不再需要类,我从未使用它时)需要显式调用FileCleaningTracker.exitWhenFinished()或者让Spring执行此操作(参见上文)。 有些第三方库可能会使用它并且没有正确关闭 – 这意味着它有一个错误。

  • pool-1-thread-22 – 这是Executors实用程序创建的线程之一。 确保在关闭期间在应用程序中的每个此类池上调用shutdown()

  • org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2 – Quartz工作线程(实际运行作业的线程)。 SchedulerFactoryBean会自动关闭调度程序,我认为Tomcat在这里是错误的,我也常常看到这个错误。 然而,将SchedulerFactoryBean.waitForJobsToCompleteOnShutdown设置为true看起来就像解决了这个问题。

  • com.iteezy.shared.domain.DirEntry.data – 我不确定这个。 它是您自己的线程,需要在关机时中断或H2数据库线程(?)需要检查其堆栈以猜测它来自何处。

底线是:不要只是杀死所有移动的东西(实际上,Tomcat在发出此警告后为您执行此操作)但确定线程来自何处并使用特定于框架/库的close()方法以允许进一步清理。 要温柔。

设置一个Servlet来管理它的destroy()方法。 线程可以检查标志以查看它们是否必须继续。

在servlet中,在destroy方法中执行以下操作。 您显然需要能够访问Collection但是如何获得这取决于您的系统设置方式。

 destroy() { for (MyThread thread : myThreads) { thread.stopProcessing(); } } 

您的MyThread类将具有以下内容:

 public class MyThread { private boolean finished = false; @Override public void run() { while (!finished) { //do something } } public void stopProcessing() { finished = true; } } 

正确关闭您的webapp。 不要让这些线程运行。

或者,不要继续重新部署webapp。