我已经开发了一个Webbapp,它可以广泛使用线程。我们需要以固定的时间间隔监视一些资源,然后采取行动。
为此,我们开发了一种ThreadManager
,将包装为一个 ScheduledThreadPoolExecutor
。我们允许执行程序的任何方法,我们仅使用此管理器来确保每个人都使用相同的线程池实例(该管理器是Singleton ...)
然后,当我们关闭上下文时,我们有一个ServletContextListener
,它负责正确关闭执行程序:
ejecutor.shutdown();
try
{
ejecutor.awaitTermination(10, TimeUnit.SECONDS);
}
catch (InterruptedException ie)
{
Thread.currentThread().interrupt();
}
System.out.println("Llamo al shutdownnow");
ejecutor.shutdownNow();
ejecutor = null;
但是然后,当我们关闭tomcat/unload上下文时,我们得到很多错误,它们是:
GRAVE: The web application [/qsys] appears to have started a thread named [pool-4-thread-1] but has failed to stop it. This is very likely to create a memory leak.
如果我们通过询问 Activity 线程的数量来监视执行程序,则在关闭后,它会继续说不再有 Activity 线程,但我们会继续在tomcat上找到相同的错误。
有任何想法吗?
更新:提供了更多信息
挂起的线程是在
Executor
中调度的线程。它们所有人都覆盖interrupt()
,因此它类似于:System.out.println("Me intentan interrumpir!!");
run = false;
super.interrupt();
然后,在
contextDestroyed
期间,我执行了已经提到的关闭...但是从中断中退出的系统甚至都没有被打印出来!执行者将
ExecuteExistingDelayedTasksAfterShutdownPolicy
设置为false ...仍然保持线程活跃...
最佳答案
最后,我发现了一些东西:
我每次使用ScheduledThreadPoolExecutor
tomcat每次都无法在undeploy/close/restart上关闭池化线程,从而导致可能的内存泄漏(应该没问题,因为tomcat无法关闭它们,但是在杀死它们之后,所以没有问题,但客户不允许。
实际上,我创建了一个ScheduledThreadPoolExecutor,其核心大小为25,然后将其关闭(没有运行或计划的任何时间),并且tomcat仍然无法清理池化线程。
所以我的解决方案是在等待补丁时使用计时器...(tomcat 6.0和jdk 1.5.0_22发生了这种情况)
关于java - 使用tomcat的可能的内存泄漏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3819817/