java.lang.Thread.State 中 90% 线程的分析:等待(停车)
Analysis of 90% threads in java.lang.Thread.State: WAITING (parking)
我的 tomcat 应用程序服务器中的线程数每天都在 增长 。
当我对线程转储进行分析时。
我发现在430个线程中有307个线程处于这种状态。
示例堆栈跟踪
"pool-283-thread-1" #2308674 prio=5 os_prio=0 tid=0x000000000a916800 nid=0x1101 waiting on condition [0x00002aec87f17000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000006d9929ec0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
"pool-282-thread-1" #2307106 prio=5 os_prio=0 tid=0x000000000a4fb000 nid=0x78e3 waiting on condition [0x00002aec87e16000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000006d8ca7bf8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
环境
JDK: jdk1.8.0_60
OS: Linux
Tomcat: tomcat-7.0.65
不确定这是否是导致问题的原因。
感谢任何帮助。
这是典型的资源泄漏。您在应用程序的某处使用了某种 ExecutorService
并且在工作完成后您没有关闭该池导致线程永远等待。
您应该在工作完成后调用 ExecutorService#shutdown()
关闭池和 release/terminate 它的线程。
像pool-282-thread-1
pool-283-thread-1
这样的线程名称表明您很可能正在使用单线程池执行器(因为池号很大而线程号只有1)。 ExecutorService
背后的想法是重用空闲的线程来做更多的工作。因此,与其每次需要做一些后台工作时都创建新的 ExecutorService
,不如共享单个实例并在您的应用程序中使用它。
这个问题发生在我们的应用程序中。我们通过使用 单个 ExecutorService 而不是每次都创建 ExecutorService 来修复它。
我的 tomcat 应用程序服务器中的线程数每天都在 增长 。
当我对线程转储进行分析时。
我发现在430个线程中有307个线程处于这种状态。
示例堆栈跟踪
"pool-283-thread-1" #2308674 prio=5 os_prio=0 tid=0x000000000a916800 nid=0x1101 waiting on condition [0x00002aec87f17000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000006d9929ec0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
"pool-282-thread-1" #2307106 prio=5 os_prio=0 tid=0x000000000a4fb000 nid=0x78e3 waiting on condition [0x00002aec87e16000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000006d8ca7bf8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
环境
JDK: jdk1.8.0_60
OS: Linux
Tomcat: tomcat-7.0.65
不确定这是否是导致问题的原因。
感谢任何帮助。
这是典型的资源泄漏。您在应用程序的某处使用了某种 ExecutorService
并且在工作完成后您没有关闭该池导致线程永远等待。
您应该在工作完成后调用 ExecutorService#shutdown()
关闭池和 release/terminate 它的线程。
像pool-282-thread-1
pool-283-thread-1
这样的线程名称表明您很可能正在使用单线程池执行器(因为池号很大而线程号只有1)。 ExecutorService
背后的想法是重用空闲的线程来做更多的工作。因此,与其每次需要做一些后台工作时都创建新的 ExecutorService
,不如共享单个实例并在您的应用程序中使用它。
这个问题发生在我们的应用程序中。我们通过使用 单个 ExecutorService 而不是每次都创建 ExecutorService 来修复它。