线程转储文件分析模式 – 条条大路通罗马

描述

如果线程转储文件中的多个线程最终都调用了同一个方法,那么这可能需要引起您的关注。在存在问题的大多数情况下(比如:数据源响应迟缓、锁未释放、无限循环线程等等),会出现大量线程调用同一个方法的情况。我们需要对这个方法进行详细的分析。

示例

此处应用程序使用 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

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at WordPress.com.

Up ↑

%d bloggers like this: