我已经开发了一个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/

10-11 22:22
查看更多