LoginSignup
49

More than 5 years have passed since last update.

JavaでCPUを占有しているスレッドを探せ!

Posted at

やり方

CPUの高いプロセスを探す

対象のプロセスを探す為、以下のコマンドにて一覧を表示する。

# top -Hc -n 1 -p `pgrep java`

オプション「-Hc」は、スレッド単位でCPUの降順で出力する。
オプション「-n 1」は、1回だけ表示する。
オプション「-p `pgrep java`」は、Javaのプロセス番号を設定する。
「jps」コマンドを利用して、特定しても良い。

以下の様な結果が得られる。

   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                   
  5844 tomcat    20   0 2105m 281m  12m R 99.6 15.1   0:35.87 /usr/lib/jvm/java/bin/java
  5824 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:00.03 /usr/lib/jvm/java/bin/java
  5828 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:04.19 /usr/lib/jvm/java/bin/java
  5830 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:01.02 /usr/lib/jvm/java/bin/java
  5831 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:01.27 /usr/lib/jvm/java/bin/java
  5832 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:00.33 /usr/lib/jvm/java/bin/java
  5833 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:00.01 /usr/lib/jvm/java/bin/java
  5834 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:00.00 /usr/lib/jvm/java/bin/java
  5835 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:00.01 /usr/lib/jvm/java/bin/java
  5836 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:01.11 /usr/lib/jvm/java/bin/java
  5837 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:01.30 /usr/lib/jvm/java/bin/java
  5838 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:00.00 /usr/lib/jvm/java/bin/java
  5839 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:00.17 /usr/lib/jvm/java/bin/java
  5842 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:00.00 /usr/lib/jvm/java/bin/java
  5845 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:00.00 /usr/lib/jvm/java/bin/java
  5846 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:00.00 /usr/lib/jvm/java/bin/java
  5847 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:00.00 /usr/lib/jvm/java/bin/java
  5848 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:00.00 /usr/lib/jvm/java/bin/java
  5849 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:00.00 /usr/lib/jvm/java/bin/java
  5850 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:00.02 /usr/lib/jvm/java/bin/java
  5851 tomcat    20   0 2105m 281m  12m S  0.0 15.1   0:00.03 /usr/lib/jvm/java/bin/java

以上の結果から、PID「5844」がCPUを「99.6%」使っている事がわかる。

プロセス番号を16進数にする

コマンドで求める。(手抜き)

# printf "%x\n" [PID]
# printf "%x\n" 5844
# 16d4

スレッドの一覧を取得し対象のプロセスを探す*

# jstack `pgrep java` > /tmp/jstack.log
# vi /tmp/jstack.log

スレッドの一覧から、「nid=0x[PID16進数]」を探す。
ここだと、「nid=0x16d4」が該当するスレッドとなる。

"Fuka Thread" prio=10 tid=0x00007f65e42b6800 nid=0x16d4 runnable [0x00007f65c1f55000]
   java.lang.Thread.State: RUNNABLE at
   sun.security.provider.SHA.implDigest(SHA.java:98) at
   sun.security.provider.DigestBase.engineDigest(DigestBase.java:173) at
   sun.security.provider.DigestBase.engineDigest(DigestBase.java:152) at
   java.security.MessageDigest$Delegate.engineDigest(MessageDigest.java:576) at
   java.security.MessageDigest.digest(MessageDigest.java:353) at
   fuka.FukaListerner.run(FukaListerner.java:63) at
   java.lang.Thread.run(Thread.java:745)

上記の様にスレッドが見つかる。
ここでは、「Fuka Thread」というスレッドが、
「SHA」ダイジェストの計算でCPU負荷を上げているように見える。

あとは、ソースコードを追っかけて対象箇所を探す。


補足

CentOSでyumインストールした、OpenJDK1.7+tomcatでは、
「jstack」単体だと、上手く動かなかった。
「sudo -u tomcat jstack」とユーザを指定する事で正常に動いた。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
49