我有一个spring boot(1.5.2)Web应用程序,它在tomcat(8.5)中作为唯一的Web应用程序运行。 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的情况下,永远不会重新部署该应用程序。
我的问题是,是否有人遇到过类似的问题,以及如何解决这些问题,如果没有,我如何诊断为什么创建了这些线程却之后又未将其删除。
答案 0 :(得分:0)
以这种方式产生线程的最可能原因:
maxThreads
从默认值200设置为过高的值。Executors.newCachedThreadPool()
遇到线程峰值。new Thread()
创建线程。第4点不太可能出现,因为堆栈跟踪显示java.util.concurrent.ThreadPoolExecutor
。查找创建带有前缀pool-
的线程的池(grep应用程序代码和pool-
的Tomcat配置)。然后盖好游泳池。