Linux平台上的Java应用CPU问题定位——以WebSphere为例

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

猜你喜欢

转载自blog.csdn.net/gongxsh00/article/details/80867764