我已经将我的应用程序的线程转储部署到使用logback的生产环境中。我不是分析线程转储的专家,但是我必须这样做。我正在学习它,并且已经阅读了一些在线文章。
下面是真实的线程转储:
"logback-8" #136 daemon prio=5 os_prio=0 tid=0x00007f3588001000 nid=0x13a waiting on condition [0x00007f35f8e7b000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000068d740338> (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.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
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)
"logback-7" #135 daemon prio=5 os_prio=0 tid=0x00007f356c030800 nid=0x139 waiting on condition [0x00007f35f8d7a000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000068d740338> (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.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
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)
"logback-6" #134 daemon prio=5 os_prio=0 tid=0x00007f357c018000 nid=0x138 waiting on condition [0x00007f3568ef0000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000068d740338> (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.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
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)
"logback-5" #133 daemon prio=5 os_prio=0 tid=0x00007f36b8003800 nid=0x137 waiting on condition [0x00007f35f9380000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000068d740338> (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.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
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)正如我所看到的,这些线程中的大多数都处于等待状态。
但是我怎么知道他们到底在等什么呢?这些线程都在试图“等待”“某些东西”吗?
我确实阅读了一些在线材料,但当我看到一个真正的线程转储时,我不明白如何采取步骤来理解这些线程到底想做什么,以及它们在等待什么,被阻塞等等。
有没有人能帮我理解一下?
发布于 2019-09-10 12:58:45
就我所分析的线程转储而言,当你使用像Spring这样的框架,或者像你在这里使用的其他库一样,Logback。它们会根据你的配置创建线程池。例如,您可以在applicationcontext.xml或任何基于java的配置类中找到这样的配置。因此,它所做的是,它将在应用程序启动或第一次初始化调用时创建那么多线程。如果有任何任务到来,框架将从池中挑选一个线程并分配它。任务完成后,线程将返回到池中,此时线程状态将类似于等待(驻留)。这并不意味着它被任何线程阻塞。如果您的服务器有足够的能力处理这样的池,那么它不会引起任何性能问题。他们只是坐得很好,因为他们没有任何任务要做。
你可以在this上找到更多信息,如果你想查看线程转储的可视化分析方法,那么你可以使用this。我发现这个网站很有帮助。只需上传您的转储file.It就会告诉您线程转储需要知道的所有事情。
发布于 2019-09-21 17:35:51
基于上面的堆栈跟踪,以下是推论
这些作业将从队列中取出,并由ThreadPoolExecutors中的线程执行(可以是Q.
)。
让我们假设,我们有一个只有两个线程(固定大小)的线程池执行器,并且您只向队列提交了一个作业。(Job1)
Thread1从队列中获取job1并执行。一旦执行结束,它就进入等待状态,因为队列中没有元素。它没有工作要做。堆栈跟踪中存在等待线程并不意味着它们是有害的。
发布于 2019-09-22 20:19:13
您可能要做的第一件事是搜索Runnable线程和它锁定的同步器。Runnable线程如果挂起了很长时间,那么它很有可能正在执行IO或DB操作。以30秒左右的间隔进行后续线程转储,并进行比较研究。
https://stackoverflow.com/questions/57864026
复制相似问题