`
kavy
  • 浏览: 888468 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

How to Analyze Java Thread Dumps

 
阅读更多
The Performance Zone is supported by New Relic and AppDynamics. Both are leaders in the APM space with high-profile customers and massive cost reductions for those users.

The content of this article was originally written by Tae Jin Gu on the Cubrid blog

When there is an obstacle, or when a Java based Web application is running much slower than expected, we need to use thread dumps. If thread dumps feel like very complicated to you, this article may help you very much. Here I will explain what threads are in Java, their types, how they are created, how to manage them, how you can dump threads from a running application, and finally how you can analyze them and determine the bottleneck or blocking threads. This article is a result of long experience in Java application debugging.

Java and Thread

A web server uses tens to hundreds of threads to process a large number of concurrent users. If two or more threads utilize the same resources, a contentionbetween the threads is inevitable, and sometimes deadlock occurs.

Thread contention is a status in which one thread is waiting for a lock, held by another thread, to be lifted. Different threads frequently access shared resources on a web application. For example, to record a log, the thread trying to record the log must obtain a lock and access the shared resources.

Deadlock is a special type of thread contention, in which two or more threads are waiting for the other threads to complete their tasks in order to complete their own tasks.

Different issues can arise from thread contention. To analyze such issues, you need to use the thread dump. A thread dump will give you the information on the exact status of each thread.

Background Information for Java Threads

Thread Synchronization

A thread can be processed with other threads at the same time. In order to ensure compatibility when multiple threads are trying to use shared resources, one thread at a time should be allowed to access the shared resources by using thread synchronization.

Thread synchronization on Java can be done using monitor. Every Java object has a single monitor. The monitor can be owned by only one thread. For a thread to own a monitor that is owned by a different thread, it needs to wait in the wait queue until the other thread releases its monitor.

Thread Status

In order to analyze a thread dump, you need to know the status of threads. The statuses of threads are stated on java.lang.Thread.State.

  Thread Status.

Figure 1: Thread Status.

  • NEW: The thread is created but has not been processed yet.
  • RUNNABLE: The thread is occupying the CPU and processing a task. (It may be in WAITING status due to the OS's resource distribution.)
  • BLOCKED: The thread is waiting for a different thread to release its lock in order to get the monitor lock.
  • WAITING: The thread is waiting by using a wait, join or park method.
  • TIMED_WAITING: The thread is waiting by using a sleep, wait, join or park method. (The difference from WAITING is that the maximum waiting time is specified by the method parameter, and WAITING can be relieved by time as well as external changes.) 

Thread Types

Java threads can be divided into two:

  1. daemon threads;
  2. and non-daemon threads.

Daemon threads stop working when there are no other non-daemon threads. Even if you do not create any threads, the Java application will create several threads by default. Most of them are daemon threads, mainly for processing tasks such as garbage collection or JMX.

A thread running the 'static void main(String[] args)’ method is created as a non-daemon thread, and when this thread stops working, all other daemon threads will stop as well. (The thread running this main method is called the VM thread in HotSpot VM.)

Getting a Thread Dump

We will introduce the three most commonly used methods. Note that there are many other ways to get a thread dump. A thread dump can only show the thread status at the time of measurement, so in order to see the change in thread status, it is recommended to extract them from 5 to 10 times with 5-second intervals.

Getting a Thread Dump Using jstack

In JDK 1.6 and higher, it is possible to get a thread dump on MS Windows usingjstack.

Use PID via jps to check the PID of the currently running Java application process.

1.[user@linux ~]$ jps -v
2. 
3.25780 RemoteTestRunner -Dfile.encoding=UTF-8
4.25590 sub.rmi.registry.RegistryImpl 2999 -Dapplication.home=/home1/user/java/jdk.1.6.0_24 -Xms8m
5.26300 sun.tools.jps.Jps -mlvV -Dapplication.home=/home1/user/java/jdk.1.6.0_24 -Xms8m

Use the extracted PID as the parameter of jstack to obtain a thread dump.

1.[user@linux ~]$ jstack -f 5824

A Thread Dump Using jVisualVM

Generate a thread dump by using a program such as jVisualVM.

  A Thread Dump Using visualvm.

Figure 2:  A Thread Dump Using visualvm.

The task on the left indicates the list of currently running processes. Click on the process for which you want the information, and select the thread tab to check the thread information in real time. Click the Thread Dump button on the top right corner to get the thread dump file.

Generating in a Linux Terminal

Obtain the process pid by using ps -ef command to check the pid of the currently running Java process.

1.[user@linux ~]$ ps - ef | grep java
2. 
3.user      2477          1    0 Dec23 ?         00:10:45 ...
4.user    25780 25361   0 15:02 pts/3    00:00:02 ./jstatd -J -Djava.security.policy=jstatd.all.policy -p 2999
5.user    26335 25361   0 15:49 pts/3    00:00:00 grep java

Use the extracted pid as the parameter of kill –SIGQUIT(3) to obtain a thread dump.

Thread Information from the Thread Dump File

01."pool-1-thread-13" prio=6 tid=0x000000000729a000 nid=0x2fb4 runnable [0x0000000007f0f000] java.lang.Thread.State: RUNNABLE
02.at java.net.SocketInputStream.socketRead0(Native Method)
03. 
04.at java.net.SocketInputStream.read(SocketInputStream.java:129)
05. 
06.at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
07. 
08.at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
09. 
10.at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
11. 
12.- locked <0x0000000780b7e688> (a java.io.InputStreamReader)
13. 
14.at java.io.InputStreamReader.read(InputStreamReader.java:167)
15. 
16.at java.io.BufferedReader.fill(BufferedReader.java:136)
17. 
18.at java.io.BufferedReader.readLine(BufferedReader.java:299)
19. 
20.- locked <0x0000000780b7e688> (a java.io.InputStreamReader)
21. 
22.at java.io.BufferedReader.readLine(BufferedReader.java:362)
)
  • Thread name: When using Java.lang.Thread class to generate a thread, the thread will be named Thread-(Number), whereas when using java.util.concurrent.ThreadFactory class, it will be named pool-(number)-thread-(number).
  • Priority: Represents the priority of the threads.
  • Thread ID: Represents the unique ID for the threads. (Some useful information, including the CPU usage or memory usage of the thread, can be obtained by using thread ID.)
  • Thread status: Represents the status of the threads.
  • Thread callstack: Represents the call stack information of the threads. 

Thread Dump Patterns by Type

When Unable to Obtain a Lock (BLOCKED)

This is when the overall performance of the application slows down because a thread is occupying the lock and prevents other threads from obtaining it. In the following example, BLOCKED_TEST pool-1-thread-1 thread is running with <0x0000000780a000b0> lock, while BLOCKED_TEST pool-1-thread-2 and BLOCKED_TEST pool-1-thread-3 threads are waiting to obtain <0x0000000780a000b0> lock.

 A thread blocking other threads

Figure 3: A thread blocking other threads.

01."BLOCKED_TEST pool-1-thread-1" prio=6 tid=0x0000000006904800 nid=0x28f4 runnable [0x000000000785f000]
02.java.lang.Thread.State: RUNNABLE
03.at java.io.FileOutputStream.writeBytes(Native Method)
04.at java.io.FileOutputStream.write(FileOutputStream.java:282)
05.at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
06.at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
07.- locked <0x0000000780a31778> (a java.io.BufferedOutputStream)
08.at java.io.PrintStream.write(PrintStream.java:432)
09.- locked <0x0000000780a04118> (a java.io.PrintStream)
10.at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
11.at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
12.at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:85)
13.- locked <0x0000000780a040c0> (a java.io.OutputStreamWriter)
14.at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:168)
15.at java.io.PrintStream.newLine(PrintStream.java:496)
16.- locked <0x0000000780a04118> (a java.io.PrintStream)
17.at java.io.PrintStream.println(PrintStream.java:687)
18.- locked <0x0000000780a04118> (a java.io.PrintStream)
19.at com.nbp.theplatform.threaddump.ThreadBlockedState.monitorLock(ThreadBlockedState.java:44)
20.- locked <0x0000000780a000b0> (a com.nbp.theplatform.threaddump.ThreadBlockedState)
21.at com.nbp.theplatform.threaddump.ThreadBlockedState$1.run(ThreadBlockedState.java:7)
22.at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
23.at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
24.at java.lang.Thread.run(Thread.java:662)
25. 
26.Locked ownable synchronizers:
27.- <0x0000000780a31758> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
28. 
29."BLOCKED_TEST pool-1-thread-2" prio=6 tid=0x0000000007673800 nid=0x260c waiting for monitor entry [0x0000000008abf000]
30.java.lang.Thread.State: BLOCKED (on object monitor)
31.at com.nbp.theplatform.threaddump.ThreadBlockedState.monitorLock(ThreadBlockedState.java:43)
32.- waiting to lock <0x0000000780a000b0> (a com.nbp.theplatform.threaddump.ThreadBlockedState)
33.at com.nbp.theplatform.threaddump.ThreadBlockedState$2.run(ThreadBlockedState.java:26)
34.at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
35.at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
36.at java.lang.Thread.run(Thread.java:662)
37. 
38.Locked ownable synchronizers:
39.- <0x0000000780b0c6a0> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
40. 
41."BLOCKED_TEST pool-1-thread-3" prio=6 tid=0x00000000074f5800 nid=0x1994 waiting for monitor entry [0x0000000008bbf000]
42.java.lang.Thread.State: BLOCKED (on object monitor)
43.at com.nbp.theplatform.threaddump.ThreadBlockedState.monitorLock(ThreadBlockedState.java:42)
44.- waiting to lock <0x0000000780a000b0> (a com.nbp.theplatform.threaddump.ThreadBlockedState)
45.at com.nbp.theplatform.threaddump.ThreadBlockedState$3.run(ThreadBlockedState.java:34)
46.at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886
47.at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
48.at java.lang.Thread.run(Thread.java:662)
49. 
50.Locked ownable synchronizers:
51.- <0x0000000780b0e1b8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)

When in Deadlock Status

This is when thread A needs to obtain thread B's lock to continue its task, whilethread B needs to obtain thread A's lock to continue its task. In the thread dump, you can see that DEADLOCK_TEST-1 thread has 0x00000007d58f5e48 lock, and is trying to obtain 0x00000007d58f5e60 lock. You can also see that DEADLOCK_TEST-2 thread has 0x00000007d58f5e60 lock, and is trying to obtain 0x00000007d58f5e78 lock. Also, DEADLOCK_TEST-3 thread has 0x00000007d58f5e78 lock, and is trying to obtain 0x00000007d58f5e48 lock. As you can see, each thread is waiting to obtain another thread's lock, and this status will not change until one thread discards its lock.

 Threads in a Deadlock status

Figure 4: Threads in a Deadlock status.

 

01."DEADLOCK_TEST-1" daemon prio=6 tid=0x000000000690f800 nid=0x1820 waiting for monitor entry [0x000000000805f000]
02.java.lang.Thread.State: BLOCKED (on object monitor)
03.at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197)
04.- waiting to lock <0x00000007d58f5e60> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
05.at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182)
06.- locked <0x00000007d58f5e48> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
07.at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)
08. 
09.Locked ownable synchronizers:
10.- None
11. 
12."DEADLOCK_TEST-2" daemon prio=6 tid=0x0000000006858800 nid=0x17b8 waiting for monitor entry [0x000000000815f000]
13.java.lang.Thread.State: BLOCKED (on object monitor)
14.at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197)
15.- waiting to lock <0x00000007d58f5e78> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
16.at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182)
17.- locked <0x00000007d58f5e60> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
18.at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)
19. 
20.Locked ownable synchronizers:
21.- None
22. 
23."DEADLOCK_TEST-3" daemon prio=6 tid=0x0000000006859000 nid=0x25dc waiting for monitor entry [0x000000000825f000]
24.java.lang.Thread.State: BLOCKED (on object monitor)
25.at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197)
26.- waiting to lock <0x00000007d58f5e48> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
27.at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182)
28.- locked <0x00000007d58f5e78> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
29.at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)
30. 
31.Locked ownable synchronizers:
32.- None

When Continuously Waiting to Receive Messages from a Remote Server

The thread appears to be normal, since its state keeps showing as RUNNABLE. However, when you align the thread dumps chronologically, you can see that socketReadThread thread is waiting infinitely to read the socket.

 Continuous Waiting Status

Figure 5: Continuous Waiting Status.

01."socketReadThread" prio=6 tid=0x0000000006a0d800 nid=0x1b40 runnable [0x00000000089ef000]
02.java.lang.Thread.State: RUNNABLE
03.at java.net.SocketInputStream.socketRead0(Native Method)
04.at java.net.SocketInputStream.read(SocketInputStream.java:129)
05.at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
06.at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
07.at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
08.- locked <0x00000007d78a2230> (a java.io.InputStreamReader)
09.at sun.nio.cs.StreamDecoder.read0(StreamDecoder.java:107)
10.- locked <0x00000007d78a2230> (a java.io.InputStreamReader)
11.at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:93)
12.at java.io.InputStreamReader.read(InputStreamReader.java:151)
13.at com.nbp.theplatform.threaddump.ThreadSocketReadState$1.run(ThreadSocketReadState.java:27)
14.at java.lang.Thread.run(Thread.java:662)

When Waiting

The thread is maintaining WAIT status. In the thread dump, IoWaitThread thread keeps waiting to receive a message from LinkedBlockingQueue. If there continues to be no message for LinkedBlockingQueue, then the thread status will not change.

 Waiting status

Figure 6: Waiting status.

01."IoWaitThread" prio=6 tid=0x0000000007334800 nid=0x2b3c waiting on condition [0x000000000893f000]
02.java.lang.Thread.State: WAITING (parking)
03.at sun.misc.Unsafe.park(Native Method)
04.- parking to wait for  <0x00000007d5c45850> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
05.at java.util.concurrent.locks.LockSupport.park(LockSupport.java:156)
06.at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1987)
07.at java.util.concurrent.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:440)
08.at java.util.concurrent.LinkedBlockingDeque.take(LinkedBlockingDeque.java:629)
09.at com.nbp.theplatform.threaddump.ThreadIoWaitState$IoWaitHandler2.run(ThreadIoWaitState.java:89)
10.at java.lang.Thread.run(Thread.java:662)

When Thread Resources Cannot be Organized Normally

Unnecessary threads will pile up when thread resources cannot be organized normally. If this occurs, it is recommended to monitor the thread organization process or check the conditions for thread termination.

 Unorganized Threads

Figure 7: Unorganized Threads.

How to Solve Problems by Using Thread Dump

Example 1: When the CPU Usage is Abnormally High

1. Extract the thread that has the highest CPU usage.

1.[user@linux ~]$ ps -mo pid.lwp.stime.time.cpu -C java
2. 
3.PID         LWP          STIME                  TIME        %CPU
4.10029               -         Dec07          00:02:02           99.5
5.-       10039        Dec07          00:00:00              0.1
6.-       10040        Dec07          00:00:00           95.5

 

From the application, find out which thread is using the CPU the most.

Acquire the Light Weight Process (LWP) that uses the CPU the most and convert its unique number (10039) into a hexadecimal number (0x2737).

2. After acquiring the thread dump, check the thread's action.

Extract the thread dump of an application with a PID of 10029, then find the thread with an nid of 0x2737.

01."NioProcessor-2" prio=10 tid=0x0a8d2800 nid=0x2737 runnable [0x49aa5000]
02.java.lang.Thread.State: RUNNABLE
03.at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
04.at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:210)
05.at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65)
06.at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)
07.- locked <0x74c52678> (a sun.nio.ch.Util$1)
08.- locked <0x74c52668> (a java.util.Collections$UnmodifiableSet)
09.- locked <0x74c501b0> (a sun.nio.ch.EPollSelectorImpl)
10.at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)
11.at external.org.apache.mina.transport.socket.nio.NioProcessor.select(NioProcessor.java:65)
12.at external.org.apache.mina.common.AbstractPollingIoProcessor$Worker.run(AbstractPollingIoProcessor.java:708)
13.at external.org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51)
14.at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
15.at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
16.at java.lang.Thread.run(Thread.java:662)

Extract thread dumps several times every hour, and check the status change of the threads to determine the problem.

Example 2: When the Processing Performance is Abnormally Slow  

After acquiring thread dumps several times, find the list of threads with BLOCKED status.

01." DB-Processor-13" daemon prio=5 tid=0x003edf98 nid=0xca waiting for monitor entry [0x000000000825f000]
02.java.lang.Thread.State: BLOCKED (on object monitor)
03.at beans.ConnectionPool.getConnection(ConnectionPool.java:102)
04.- waiting to lock <0xe0375410> (a beans.ConnectionPool)
05.at beans.cus.ServiceCnt.getTodayCount(ServiceCnt.java:111)
06.at beans.cus.ServiceCnt.insertCount(ServiceCnt.java:43)
07. 
08."DB-Processor-14" daemon prio=5 tid=0x003edf98 nid=0xca waiting for monitor entry [0x000000000825f020]
09.java.lang.Thread.State: BLOCKED (on object monitor)
10.at beans.ConnectionPool.getConnection(ConnectionPool.java:102)
11.- waiting to lock <0xe0375410> (a beans.ConnectionPool)
12.at beans.cus.ServiceCnt.getTodayCount(ServiceCnt.java:111)
13.at beans.cus.ServiceCnt.insertCount(ServiceCnt.java:43)
14. 
15." DB-Processor-3" daemon prio=5 tid=0x00928248 nid=0x8b waiting for monitor entry [0x000000000825d080]
16.java.lang.Thread.State: RUNNABLE
17.at oracle.jdbc.driver.OracleConnection.isClosed(OracleConnection.java:570)
18.- waiting to lock <0xe03ba2e0> (a oracle.jdbc.driver.OracleConnection)
19.at beans.ConnectionPool.getConnection(ConnectionPool.java:112)
20.- locked <0xe0386580> (a java.util.Vector)
21.- locked <0xe0375410> (a beans.ConnectionPool)
22.at beans.cus.Cue_1700c.GetNationList(Cue_1700c.java:66)
23.at org.apache.jsp.cue_1700c_jsp._jspService(cue_1700c_jsp.java:120)

Acquire the list of threads with BLOCKED status after getting the thread dumps several times.

If the threads are BLOCKED, extract the threads related to the lock that the threads are trying to obtain.

Through the thread dump, you can confirm that the thread status stays BLOCKED because <0xe0375410> lock could not be obtained. This problem can be solved by analyzing stack trace from the thread currently holding the lock.

There are two reasons why the above pattern frequently appears in applications using DBMS. The first reason is inadequate configurations. Despite the fact that the threads are still working, they cannot show their best performance because the configurations for DBCP and the like are not adequate. If you extract thread dumps multiple times and compare them, you will often see that some of the threads that were BLOCKED previously are in a different state.

The second reason is the abnormal connection. When the connection with DBMS stays abnormal, the threads wait until the time is out. In this case, even after extracting the thread dumps several times and comparing them, you will see that the threads related to DBMS are still in a BLOCKED state. By adequately changing the values, such as the timeout value, you can shorten the time in which the problem occurs.

Coding for Easy Thread Dump

Naming Threads

When a thread is created using java.lang.Thread object, the thread will be named Thread-(Number). When a thread is created using java.util.concurrent.DefaultThreadFactory object, the thread will be named pool-(Number)-thread-(Number). When analyzing tens to thousands of threads for an application, if all the threads still have their default names, analyzing them becomes very difficult, because it is difficult to distinguish the threads to be analyzed.

Therefore, you are recommended to develop the habit of naming the threads whenever a new thread is created. 

When you create a thread using java.lang.Thread, you can give the thread a custom name by using the creator parameter.

1.public Thread(Runnable target, String name);
2.public Thread(ThreadGroup group, String name);
3.public Thread(ThreadGroup group, Runnable target, String name);
4.public Thread(ThreadGroup group, Runnable target, String name, long stackSize);

When you create a thread using java.util.concurrent.ThreadFactory, you can name it by generating your own ThreadFactory. If you do not need special functionalities, then you can use MyThreadFactory as described below:

01.import java.util.concurrent.ConcurrentHashMap;
02.import java.util.concurrent.ThreadFactory;
03.import java.util.concurrent.atomic.AtomicInteger;
04. 
05.public class MyThreadFactory implements ThreadFactory {
06.private static final ConcurrentHashMap<String, AtomicInteger> POOL_NUMBER =
07.new ConcurrentHashMap<String, AtomicInteger>();
08.private final ThreadGroup group;
09.private final AtomicInteger threadNumber = new AtomicInteger(1);
10.private final String namePrefix;
11. 
12.public MyThreadFactory(String threadPoolName) {
13. 
14.if (threadPoolName == null) {
15.throw new NullPointerException("threadPoolName");
16.}
17.POOL_NUMBER.putIfAbsent(threadPoolName, new AtomicInteger());
18. 
19.SecurityManager securityManager = System.getSecurityManager();
20.group = (securityManager != null) ? securityManager.getThreadGroup() :
21.Thread.currentThread().getThreadGroup();
22. 
23.AtomicInteger poolCount = POOL_NUMBER.get(threadPoolName);
24. 
25.if (poolCount == null) {
26.namePrefix = threadPoolName + " pool-00-thread-";
27.else {
28.namePrefix = threadPoolName + " pool-" + poolCount.getAndIncrement() + "-thread-";
29.}
30.}
31. 
32.public Thread newThread(Runnable runnable) {
33.Thread thread = new Thread(group, runnable, namePrefix + threadNumber.getAndIncrement(), 0);
34. 
35.if (thread.isDaemon()) {
36.thread.setDaemon(false);
37.}
38. 
39.if (thread.getPriority() != Thread.NORM_PRIORITY) {
40.thread.setPriority(Thread.NORM_PRIORITY);
41.}
42. 
43.return thread;
44.}
45.}

Obtaining More Detailed Information by Using MBean

You can obtain ThreadInfo objects using MBean. You can also obtain more information that would be difficult to acquire via thread dumps, by using ThreadInfo.

01.ThreadMXBean mxBean = ManagementFactory.getThreadMXBean();
02.long[] threadIds = mxBean.getAllThreadIds();
03.ThreadInfo[] threadInfos =
04.mxBean.getThreadInfo(threadIds);
05. 
06.for (ThreadInfo threadInfo : threadInfos) {
07.System.out.println(
08.threadInfo.getThreadName());
09.System.out.println(
10.threadInfo.getBlockedCount());
11.System.out.println(
12.threadInfo.getBlockedTime());
13.System.out.println(
14.threadInfo.getWaitedCount());
15.System.out.println(
16.threadInfo.getWaitedTime());
17.}

You can acquire the amount of time that the threads WAITed or were BLOCKED by using the method in ThreadInfo, and by using this you can also obtain the list of threads that have been inactive for an abnormally long period of time.

In Conclusion

In this article I was concerned that for developers with a lot of experience in multi-thread programming, this material may be common knowledge, whereas for less experienced developers, I felt that I was skipping straight to thread dumps, without providing enough background information about the thread activities. This was because of my lack of knowledge, as I was not able to explain the thread activities in a clear yet concise manner. I sincerely hope that this article will prove helpful for many developers.

 

 

 

 

 

 

 
Published at DZone with permission of Esen Sagynov, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Scalability and better performance are constant concerns for the developer and operations manager. New Relic and AppDynamics are dedicated to performance education as the supporters of the Performance Zone. Try both AppDynamics' fully-featured performance tool for Java, .NET, & PHP, or New Relic's free lite version to see which tool is the solution for your organization. One thing you can't afford, is no monitoring at all.

Comments

 

Raj Kllori replied on Thu, 2012/10/18 - 9:54pm

Excellent post, please do more of these kind. very detail oriented.
 

Sri Ram replied on Thu, 2012/10/18 - 11:31pm

In the first snippet, there is a typo :

>> [user@linux ~]$ ups -v

 Actually, it is 'jps -v'

In the second snippet, typo is :

>> [user@linux ~]$ jstack -f5824

Corrected : 'jstack -F 5824'

 

Esen Sagynov replied on Fri, 2012/10/19 - 12:23am in response to: Sri Ram

Thank you Sri Ram. Corrected the typos.
 

Esen Sagynov replied on Fri, 2012/10/19 - 12:28am in response to: Raj Kllori

Raj Kllori, thank you for you comment! I've already published a few other articles here at Dzone. Check out my Dzone profile. Alternatively, you can view the rest Java blogs at our CUBRID blog.
 

Devan Meyers replied on Fri, 2012/10/19 - 12:43am

Thank you for sharing all of your knowledge! Learn more about coding at www.good.is/codingforgood - Learn to code, submit a project, get a job based on your ability to learn and work hard! Or just learn coding from their cool lessons.
 

Amit Shah replied on Wed, 2012/10/24 - 7:49pm

Nice article. Recently I have been looking out for ways to schedule periodic thread dumps automatically through some JMX trigger. One way to do this I came across is through JNI - http://bwithers.wordpress.com/2007/12/29/schedule-your-own-java-thread-dumps/. Sounds complex to integrate into production code. I am looking out to using Runtime.exec("jstack") option. I am not sure what are the drawbacks of this approach.

The next step to this is analyzing the thread dumps. There are a couple of free tools for this - TDA & Samurai.

I would apppreciate your thoughts on the above two points (automatic thread dumps & thread dump analyzer tools).

 

Kim Yung replied on Wed, 2012/12/19 - 5:29pm

 thanks for the tutorial Analyze Java Thread Dumps, is very complicated but I will try.  I hope I succeeded.  Thank you very much essen for this tutorial.....

 

Ravi Sharda replied on Mon, 2013/08/05 - 11:14pm

Thanks for the great post Esen!! 

 

Subshiri Varman replied on Thu, 2014/01/02 - 8:10am

Hi, 

Very good article about analyzing thread dumps. 

Thank you.

 

 

 

Alessandro De S... replied on Sun, 2014/01/05 - 3:16pm in response to: Subshiri Varman

 On www.spyglasstools.com  you can find a lot of free VisualVM plugin for thread analysis and monitoring including a smart thread dumper to limit size of thread dump for Application Server environments.

分享到:
评论

相关推荐

    How to Analyze IoT Data in ThingSpeak.zip

    标题 "How to Analyze IoT Data in ThingSpeak" 指的是一个教程,它教导用户如何在ThingSpeak平台上分析物联网(IoT)数据。ThingSpeak是一个开源的物联网平台,允许用户收集、存储、可视化和分析来自各种IoT设备的...

    How to analyze Force close_crash from log

    在Android系统中,当应用程序遇到无法处理的错误时,系统会触发一个强制关闭(Force Close),也就是我们所说的“force close_crash”。这种情况通常伴随着“应用意外停止”的提示,并提供一个“强制关闭”按钮,让...

    mysql 性能优化 How to Analyze and Tune SQL Queries for Better Perfor

    MySQL 性能优化 - 查询优化技术 MySQL 性能优化是数据库管理员和开发者最关心的问题之一,如何分析和优化 SQL 查询以提高性能是 MySQL 性能优化的核心技术之一。在本资源中,我们将介绍 MySQL 性能优化的基本概念、...

    Think Perl 6: How to Think Like a Computer Scientist

    Think Perl 6: How to Think Like a Computer ...Use grammars and regular expressions to analyze textual content Explore how functional programming can help you make your code simpler and more expressive

    How to Efficiently Analyze a DDR4 Interface

    DDR4接口分析是现代高速数字设计中的一个关键环节,特别是在高性能计算和数据中心应用中。Cadence公司的DDR4接口分析课程提供了深入理解如何有效地处理这一挑战的途径。在2015年的MemCon会议上,Taranjit Kukal和...

    IBM Thread and Monitor Dump Analyzer for Java (jca) 线程分析工具

    IBM提供的分析javacore和dump的内存分析工具,非常...分析线程情况 JavaCore 或 ThreadDump文件,即线程的映像,用来分析线程资源锁等情况, 可参考:https://blog.csdn.net/weixin_34129696/article/details/85868951

    IBM Thread and Monitor Dump Analyzer for Java (jca) 线程分析工具 jca45

    IBM Thread and Monitor Dump Analyzer for Java(简称 jca)。它可以识别Java线程中的挂起,死锁,资源竞争,和瓶颈。 使用方法: java -Xmx1000m -jar jca456.jar

    Real-Time Analytics Techniques to Analyze

    标题“Real-Time Analytics Techniques to Analyze”中蕴含的知识点主要包括实时数据分析的各个技术面。描述部分则强调了实时大数据分析的重要性,以及对大数据学习者的价值。标签“storm spark flume”则直接指明了...

    Hadoop from the beginning: The basics

    This book is written for anyone who needs to know how to analyze data using Hadoop. It is a good book for both Hadoop beginners and those in need of advancing their Hadoop skills. The author has ...

    A numerical method to analyze thermoacoustics in an IC engine by coupling wave equation with KIVA

    在KIVA程序中采用波动方程计算内燃机热声耦合性质的研究,舒歌群,韦静思,分析国内外对热声耦合领域的现状,比较内燃机燃烧中热声耦合过程与其他热声机械的异同,结合具体燃烧软件kiva理论,将声学模型于ki

    Network Analysis Using Wireshark 2 Cookbook

    You will learn how to analyze end-to-end IPv4 and IPv6 connectivity failures for Unicast and Multicast traffic using Wireshark. It also includes Wireshark capture files so that you can practice what ...

    MIT How to Process, Analyze and Visualize Data.zip

    《MIT如何处理、分析和可视化数据》这门课程是一份宝贵的学习资源,涵盖了数据分析和可视化的核心概念。课程可能包括了理论讲解、实例演示以及实践练习,旨在帮助学习者掌握高效的数据处理技巧,深入理解数据分析的...

    wireshark analyze

    In order to analyze ping commond, usually select wlan use filter : icmp(Internet Control Message Protocol), because ICMP is one of TCP/TP protocol. It always be used to pass control data between...

    Packt.Julia.High.Performance.2nd.Edition.rar

    After that, you will learn how to analyze Julia programs and identify issues with time and memory consumption. We teach you how to use Julia's typing facilities accurately to write high-performance ...

    Java Performance Companion(Addison,2016)

    Java® Performance Companion shows how to systematically and proactively improve Java performance with today’s advanced multicore hardware and complex operating system environments. The authors, who...

    A tool for use with clang to analyze .zip

    标题 "A tool for use with clang to analyze .zip" 指的是一款与Clang编译器配合使用的工具,专门用于分析.zip文件。Clang是LLVM项目的一部分,是一个高效的C、C++、Objective-C和Objective-C++编程语言的前端,它...

    [UE] Eye Tracking the User Experience 英文版

    how to analyze and interpret eye movement data; and how to successfully communicate eye tracking findings ☆ 出版信息:☆ [作者信息] Aga Bojko [出版机构] Rosenfeld Media [出版日期] 2013年12月12...

Global site tag (gtag.js) - Google Analytics