java - 使用tomcat可能发生内存泄漏

标签 java multithreading tomcat

我开发了一个广泛使用线程的 Webbapp。我们需要定期监控一些资源,然后采取行动。

为了实现这一点,我们开发了一个ThreadManager,它包装了一个 ScheduledThreadPoolExecutor。我们允许执行器的任何方法,我们只使用这个管理器来确保每个人都使用相同的线程池实例(管理器是一个单例...)

然后,当我们关闭上下文时,我们有一个 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/卸载上下文时,我们会收到很多错误提示:

严重:Web 应用程序 [/qsys] 似乎启动了一个名为 [pool-4-thread-1] 的线程,但未能停止它。这很可能会造成内存泄漏。

如果我们通过询问 Activity 线程数来监控执行器,关闭后,它一直说没有更多的 Activity 线程,但我们继续在 tomcat 上发现相同的错误。

有什么想法吗?

更新:提供了更多信息 挂起的线程是那些在 Executor 中调度的线程。它们都覆盖了 interrupt() ,所以它是这样的:

System.out.println("Me intentan interrumpir!!");
run = false;
super.interrupt();

然后,在 contextDestroyed 期间,我执行了已经提到的关闭...但是系统从中断中退出甚至没有被打印出来!

执行器将 ExecuteExistingDelayedTasksAfterShutdownPolicy 设置为 false...

仍然保持线程存活...

最佳答案

最后,我发现了一些东西:

每次我使用ScheduledThreadPoolExecutor tomcat 都无法在取消部署/关闭/重启时关闭池线程,从而导致可能的内存泄漏(应该没问题,因为 tomcat 无法关闭它们, 但在它杀死它们之后,所以没问题,但客户不允许它...),而其他服务器工作得很好...

事实上,我创建了一个核心大小为 25 的 ScheduledThreadPoolExecutor,然后将其关闭(没有任何运行或计划)并且 tomcat 仍然无法清理池线程。

所以我的解决方案是在等待补丁时使用计时器...(它发生在 tomcat 6.0 和 jdk 1.5.0_22 上)

关于java - 使用tomcat可能发生内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3819817/

相关文章:

java - 是否有一个简单的类封装了一个 boolean 值和一个字符串?

java - 将 Material 持久底板高度设置为屏幕高度的一半?

iphone - 如何可靠地管理后台请求?

java - Java 游戏中链表的迭代器

eclipse - 使用 Maven 的 Eclipse 中的 JSF 项目为 FacesServlet 提供 ClassNotFoundException

spring-boot - 在生产中使用 K8 部署 spring boot 微服务

java - Android - 微调器 + setOnClickListener

java - AtomicInteger 条件检查线程安全

c# - 多线程未处理的异常

maven - 从基于 maven 的项目中提取所有 jar 依赖项并将它们添加到 tomcat lib