线程转储文件分析模式 – 运动员

描述

处于‘RUNNABLE’(可运行)状态的线程会消耗 CPU。所以在对消耗较多 CPU 资源的线程转储文件进行分析时,您应该仔细检查处于‘RUNNABLE’状态的线程。通常,线程转储文件会有多个线程被分类为‘RUNNABLE’状态。不过在实际运行过程中,其中的有些不会运行,只是处于等待状态。此时 JVM 仍然会将其分类为‘RUNNABLE’。您需要学会如何将那些假装自己在运行的‘RUNNABLE’线程揪出来。

示例

下方是一段真实线程转储文件的摘录。在这些栈追踪信息中,线程并没有真的处于‘RUNNABLE’状态,极其没有主动执行任何代码。只是在等待套接字进行读写。这是因为 JVM 并不真正了解线程在原生方法中做什么,JVM 只是将其分类为‘RUNNABLE’状态。真正运行的线程会消耗 CPU。假装运行的线程则处于 I/O 等待状态,不会真的消耗 CPU。

WorkerThread#27[10.201.1.55:56893] - priority:10 - threadId:0x00002b59983cb000 - nativeId:0x4482 - addressSpace:null - state:RUNNABLE
stackTrace:
	java.lang.Thread.State: RUNNABLE
	at java.net.SocketInputStream.socketRead0(Native Method)
	at java.net.SocketInputStream.__AW_read(SocketInputStream.java:129)
	at java.net.SocketInputStream.read(SocketInputStream.java)
	at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
	at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
	- locked  (a java.io.BufferedInputStream)
	at java.io.DataInputStream.readByte(DataInputStream.java:248)
	at org.jboss.jms.server.remoting.ServerSocketWrapper.checkConnection(ServerSocketWrapper.java:94)
	at org.jboss.remoting.transport.socket.ServerThread.acknowledge(ServerThread.java:857)
	at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:585)
	at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:234)
multicast receiver,GATES-RefData-Infinispan-Cluster,matcamupa67-vm-46719 - priority:10 - threadId:0x00002b597c1ba800 - nativeId:0x3034 - addressSpace:null - state:RUNNABLE
stackTrace:
	java.lang.Thread.State: RUNNABLE
	at java.net.PlainDatagramSocketImpl.receive0(Native Method)
	- locked  (a java.net.PlainDatagramSocketImpl)
	at java.net.PlainDatagramSocketImpl.receive(PlainDatagramSocketImpl.java:145)
	- locked  (a java.net.PlainDatagramSocketImpl)
	at java.net.DatagramSocket.receive(DatagramSocket.java:725)
	- locked  (a java.net.DatagramPacket)
	- locked  (a java.net.MulticastSocket)
	at org.jgroups.protocols.UDP$PacketReceiver.__AW_run(UDP.java:675)
	at org.jgroups.protocols.UDP$PacketReceiver.run(UDP.java)
	at java.lang.Thread.run(Thread.java:662)

为什么命名为运动员模式?

维基百科将运动员定义为参与一项或多项涉及体力、速度和/或耐力的运动的人。运动员会消耗非常多的能量,这与真正可运行的线程消耗较高的 CPU 资源相似。假装 RUNNABLE 的线程则不会消耗这么多资源。

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 )

Twitter picture

You are commenting using your Twitter 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: