tomcat8 大量 http-nio 线程阻塞在waiting to lock <0x00000000feb52cf0> (a org.apache.coyote.AbstractProtocol$

来源:互联网 发布:php 类方法是否存在 编辑:程序博客网 时间:2024/06/07 08:31

最近线上应用发生了OOM , 该应用是部署在tomact8上, 发生OOM后,运维打印了线程dump和内存dump。

当时,第一反义就觉得都OOM了,打印的线程dump 和内存dump 应该不可靠,但是也没办法,看下再说。

首先,我用MAT 分析内存dump, 大小内存才用973M, 顿时很奇怪,这怎么会内存溢,由此证明,OOM

打印的内存dump 无效。


接着去分析Thread dump , 发现大量tomcat 的线程被block, 没有看到那个线程挂了业务。Tomcat8 默认是NIO, tomcat6默认是BIO。

线程信息如下:

线程栈如下:

"http-nio-9091-exec-1163" #143870 daemon prio=5 os_prio=0 tid=0x00007fc67401b000 nid=0x3c4c waiting for monitor entry [0x00007fc6e68e9000]
   java.lang.Thread.State: BLOCKED (on object monitor)

 at org.apache.coyote.AbstractProtocol$RecycledProcessors.clear(AbstractProtocol.java:877)
 - waiting to lock <0x00000000feb52cf0> (a org.apache.coyote.AbstractProtocol$RecycledProcessors)
 at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.recycle(AbstractProtocol.java:588)
 at org.apache.tomcat.util.net.NioEndpoint.releaseCaches(NioEndpoint.java:310)
 at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1610)
 at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1515)
 - locked <0x00000000cbba6658> (a org.apache.tomcat.util.net.NioChannel)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
 at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
 at java.lang.Thread.run(Thread.java:745)

看到大量的tomcat线程都阻塞在这里,我猜测,这个应该是OOM后,tomcat自身的行为,结合线程堆栈,对应响应的源码分析

发现发送OOM后,tomcat会释放资源,源码片段如下:


具体源码可以参考:http://grepcode.com/file/repo1.maven.org/maven2/org.apache.tomcat/tomcat-coyote/8.0.9/org/apache/tomcat/util/net/NioEndpoint.java

定位到这里,可以肯定OOM后,取得dump 都是失效的,没有用。


总结: thread dump 里面有线程执行的路径,对应响应的源码,就可以解释线程的状态,因此看到线程栈,不要怕,对应源码,Nothing is fear。

这个问题,也反应出,我们在jvm 启动的时候,应该配置-XX:+HeapDumpOnOutOfMemoryError.


0 0
原创粉丝点击