描述
如果线程转储文件中的多个线程最终都调用了同一个方法,那么这可能需要引起您的关注。在存在问题的大多数情况下(比如:数据源响应迟缓、锁未释放、无限循环线程等等),会出现大量线程调用同一个方法的情况。我们需要对这个方法进行详细的分析。
示例
此处应用程序使用 DataStax Java 驱动器连接至 Apache Cassandra NoSQL Database。DataStax 中存在对于 netty 库的依赖。具体而言程序使用的是以下库:
- cassandra-driver-core-2.0.1.jar
- netty-3.9.0.Final.jar
程序会突然之间遭遇“java.lang.OutOfMemoryError: unable to create new native thread”(无法创建本机线程)。根据从应用程序中获取的线程转储文件来看,大约有 2460 个处于‘可运行’状态的线程卡在方法:sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) 上。下方是其中一个线程的栈追踪信息:
"New I/O worker #211" prio=10 tid=0x00007fa06424d000 nid=0x1a58 runnable [0x00007f9f832f6000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:228)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:81)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:87)
- locked (a sun.nio.ch.Util$2)
- locked (a java.util.Collections$UnmodifiableSet)
- locked (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:98)
at org.jboss.netty.channel.socket.nio.SelectorUtil.select(SelectorUtil.java:68)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.select(AbstractNioSelector.java:415)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:212)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:89)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178)
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
说句实话,线程数有点太多了。而且全部都是 netty 库的线程。显然,问题出在 Cassandra NoSQL DB 空间不足。此问题在程序中的表现就变成了 OutOfMemoryError。在为 Cassandra DB 分配了更多空间后,问题消失。
所以记得多关注一下大部分线程都在使用的方法。
为什么将其命名为“条条大路通罗马”?
“条条大路通道罗马”是一句著名的谚语,表示不同的道路最终都走向相同的尽头。同样,在系统中出现问题时,您会发现有很大概率多个线程都在调用同一个出问题的方法。
Leave a Reply