Linux上使用命令top -H,即可看到使用CPU高的线程号,转换成16进制即可
1. 获得最顶端输出并查找与之前启动了现占用 CPU 的 WAS 的那个用户 ID 相关联的 PID。
2. 通过 kill -3 <PID> 对 WebSphere Application Server 进行若干 Thread Dump
(如果是Oracle JDK,可使用jstack <pid>来收集javacore)
3. 将步骤 1 中的 PID 号转换为一个十六进制值。
4. (用于 Linux 的 JVM 将 Java 线程作为本地线程实现,这使每个线程成为一个独立的 Linux 进程。)
5. 在 Thread Dump 中搜索native ID 的值等于上一步骤中所得到的十六进制值的线程。 这将为你揭示造成高 CPU 占用率问题的线程。
下面是 Linux 系统中上述进程的一个示例:
在 Linux 中,每个线程映射到一个进程中,所以可以找到PID。
PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME COMMAND
...........
22962 usera 9 0 86616 84M 26780 S 0.0 4.2 0:00 java
...........
如果 PID 为 22962,则十六进制值将是:0x59B2
使用此十六进制值并在 Thread Dump 中查找哪个 native ID 等于该值,以便从 Thread Dump 中获取正确的线程。
例如,如果某个线程出现问题,则 0x59B2 将对应于该线程:
3XMTHREADINFO "Servlet.Engine.Transports:915" (TID:0x34B82C78, sys_thread_t:0x778F7670, state:MW, native ID: 0x59B2) prio=5
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:415)
……
然后,您可以检查该线程以确定它正在执行的任务以及是否出现问题。
在上述示例中,由于该线程此时占用 0% 的 CPU,所以只显示执行此操作的进程。理想状态下,应当迅速并且连续完成全部三个步骤,以便尽可能及时地捕捉数据。这可以通过类似下面的一个简单的 shell 脚本来完成。
# Takes an argument (PID of the WAS process) and loops three times. This will append the prstat information to a file called dump_high_cpu.txt. The thread dump information will either be in file where stdout was redirected or printed on the screen.
for loopnum in 1 2 3
do
top -b -n1>> dump_high_cpu.txt
kill -3 $1
echo "cpu snapshot and thread dump done. #" $loopnum
sleep 1
echo "Done sleeping."
done