【发布时间】:2019-06-12 14:09:43
【问题描述】:
我有一个 Spring Boot (1.5.2) Web 应用程序,它作为唯一的 Web 应用程序在 tomcat (8.5) 中运行。 JVM(openjdk 1.8.0_181)中的线程总数几乎以恒定的速度(尽管不完全)单调增加,从一开始的几百个增加到一周内的大约 3000 个。到那时,大多数线程堆栈跟踪看起来像:
WAITING Thread[pool-917-thread-1,5,main]
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
java.lang.Thread.run(Thread.java:748)
应用程序工作正常,这些线程似乎并没有占用太多内存(至少与应用程序通常消耗的数十 GB 相比),但它们的存在表明应用程序内部存在一些隐藏的泄漏。在写这篇文章时,我目前找不到一个名为pool-.* 的线程处于不同的状态,所以我不知道他们在变成僵尸之前通常会做什么。如果不重新启动 tomcat,则永远不会重新部署应用程序。
我的问题是是否有人遇到过类似的事情以及他们是如何解决的,如果没有,我如何诊断为什么这些线程被创建而不是之后被删除。
【问题讨论】:
-
所以你的意思是说所有线程都在等待并且没有关闭。如果这是 tomcat 的问题,那么您现在很容易发现,无论如何确实提到了您正在使用的 tomcat 版本。如果是,您是否在应用程序中的任何地方设置执行器。我建议检查该代码或使用将 ThreadFactory 作为输入的构造函数。覆盖工厂中的 newThread 方法以使用自定义名称。如果它是您的应用程序,那么使用线程名称您可以轻松找出错误代码并处理该特定部分。
-
好的,它是一个工作线程池。线程名称是什么?
-
@AndyBrown 线程名称:
pool-[0-9]*-thread-1,5,main
标签: java spring tomcat threadpool