Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java死锁会降低性能_Java_Tomcat_Deadlock_Logback - Fatal编程技术网

java死锁会降低性能

java死锁会降低性能,java,tomcat,deadlock,logback,Java,Tomcat,Deadlock,Logback,我们使用java7和tomcat7运行一个web应用程序。在我们的应用程序中,性能突然下降。平均响应时间增加了一倍,在峰值时间,问题甚至变得更糟 我们打印了一个线程转储,发现一个线程一直在等待一个条件。我们做了几个线程转储,这个线程的状态从未改变 "logback-66215" daemon prio=10 tid=0x00007f86f4115800 nid=0x3758 waiting on condition [0x00007f868d817000] java.lang.Thread

我们使用java7和tomcat7运行一个web应用程序。在我们的应用程序中,性能突然下降。平均响应时间增加了一倍,在峰值时间,问题甚至变得更糟

我们打印了一个线程转储,发现一个线程一直在等待一个条件。我们做了几个线程转储,这个线程的状态从未改变

"logback-66215" daemon prio=10 tid=0x00007f86f4115800 nid=0x3758 waiting on condition [0x00007f868d817000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00007f8ddf241fa8> (a java.util.concurrent.SynchronousQueue$TransferStack)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
        at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:458)
        at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:359)
        at java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:925)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:745)
“logback-66215”守护程序prio=10 tid=0x00007f86f4115800 nid=0x3758等待条件[0x00007f868d817000]
java.lang.Thread.State:等待(停车)
在sun.misc.Unsafe.park(本机方法)
-停车等待(java.util.concurrent.SynchronousQueue$TransferStack)
位于java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
位于java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:458)
位于java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:359)
位于java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:925)
位于java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
运行(Thread.java:745)
在线程转储中找不到此线程中对0x00007f868d817000和0x00007f868d817000的引用

重新启动tomcat后,线程消失,性能恢复正常

我们正在一台12核的服务器上运行它。我们监控CPU使用情况,但没有发现峰值。在峰值负载下,由于大约每秒500个请求,CPU使用率确实上升到了800%,但没有进一步上升到1200%(这是最大值)。当它达到800%时,它就停止增加,然后性能问题当然非常糟糕

我对线程、CPU、中断的内部结构了解不够,无法完全理解这种情况。我真的很想更深入地理解这个问题


现在我的问题是:有人能解释一下,为什么这样的僵局会造成这么多麻烦?为什么它不显示在CPU使用率中,所以我们看到一个完全加载的CPU?或者这只是一个关于上下文切换的问题

如果我错了,请纠正我,但根据上面的线程转储和SynchronousQueue的存在,我猜您正在使用CachedThreadPoolExecutor(
Executors.newCachedThreadPool()
)执行某些任务

因此,转储将是其中一个缓存线程的转储,只需等待作业在线程池中排队即可。这里没什么错,这不是死锁-真正的死锁无论如何都会在线程转储中明确地声明

至于CPU消耗,处于等待状态的线程不消耗任何CPU周期,甚至不计划执行

那么,您的性能问题来自哪里

很难说,但如果我是你,我会避免使用CachedThreadPool,因为它会努力创建执行作业所需的尽可能多的线程,即使这意味着消耗所有服务器的内存(每个线程都为其堆栈保留了至少100k的内存)和CPU(如果有太多线程需要管理,您的调度程序会变得疯狂).


您可能希望手动配置ThreadPoolExecutor(而不是使用
Executors.new*
工厂),以便能够选择最大线程数、队列大小和类型,以及在出现大量作业时的退避策略。

如果我错了,请纠正我,但基于上面的线程转储,如果存在SynchronousQueue,我猜您正在使用CachedThreadPoolExecutor(
Executors.newCachedThreadPool()
)来执行某些任务

因此,转储将是其中一个缓存线程的转储,只需等待作业在线程池中排队即可。这里没什么错,这不是死锁-真正的死锁无论如何都会在线程转储中明确地声明

至于CPU消耗,处于等待状态的线程不消耗任何CPU周期,甚至不计划执行

那么,您的性能问题来自哪里

很难说,但如果我是你,我会避免使用CachedThreadPool,因为它会努力创建执行作业所需的尽可能多的线程,即使这意味着消耗所有服务器的内存(每个线程都为其堆栈保留了至少100k的内存)和CPU(如果有太多线程需要管理,您的调度程序会变得疯狂).

您可能希望手动配置ThreadPoolExecutor(而不是使用
Executors.new*
工厂),以便能够选择最大线程数、队列大小和类型,以及在出现大量作业时的退避策略