LinuxでJavaプロセスを検査しています
top -H
ただし、「COMMAND」列のスレッド名が長すぎて読み取れません。'c'を使用してプロセスのフルネームを展開すると、まだ長すぎます。
コマンドのフルネームを取得するにはどうすればよいですか?
LinuxでJavaプロセスを検査しています
top -H
ただし、「COMMAND」列のスレッド名が長すぎて読み取れません。'c'を使用してプロセスのフルネームを展開すると、まだ長すぎます。
コマンドのフルネームを取得するにはどうすればよいですか?
ツールを使用して Java スレッドを検査できますjstack。指定されたプロセス pid に属するすべてのスレッドの名前、スタック トレース、およびその他の有用な情報が一覧表示されます。
編集: jstack のスレッド ダンプのパラメーター nid は、スレッドの pid 列で top によって表示される LWP の 16 進バージョンです。
これは少し古いかもしれませんが、topとjstackをちょっとマージするために私がしたことは次のとおりです。2つのスクリプトを使用しましたが、すべてを1つで実行できると確信しています。
まず、Javaスレッドのpidを含むtopの出力をファイルに保存し、jstackの出力を別のファイルに保存します。
#!/bin/sh
top -H -b -n 1 | grep java > /tmp/top.log
jstack -l `ps fax | grep java | grep tomcat | sed "s/ *\([0-9]*\) .*/\1/g"` > /tmp/jstack.log
次に、perlスクリプトを使用してbashスクリプト(ここではcpu-java.shと呼びます)を呼び出し、2つのファイル(/tmp/top.logと/tmp/jstack.log)をマージします。
#!/usr/bin/perl
system("sh cpu-java.sh");
open LOG, "/tmp/top.log" or die $!;
print "PID\tCPU\tMem\tJStack Info\n";
while ($l = <LOG>) {
$pid = $l;
$pid =~ s/root.*//g;
$pid =~ s/ *//g;
$hex_pid = sprintf("%#x", $pid);
@values = split(/\s{2,}/, $l);
$pct = $values[4];
$mem = $values[5];
open JSTACK, "/tmp/jstack.log" or die $!;
while ($j = <JSTACK>){
if ($j =~ /.*nid=.*/){
if ($j =~ /.*$hex_pid.*/){
$j =~ s/\n//;
$pid =~ s/\n//;
print $pid . "\t" . $pct . "\t" . $mem . "\t" . $j . "\n";
}
}
}
close JSTACK;
}
close LOG;
出力は、どのスレッドがCPUを占有しているかを見つけるのに役立ちます。
PID CPU Mem JStack Info
22460 0 8.0 "main" prio=10 tid=0x083cb800 nid=0x57bc runnable [0xb6acc000]
22461 0 8.0 "GC task thread#0 (ParallelGC)" prio=10 tid=0x083d2c00 nid=0x57bd runnable
22462 0 8.0 "GC task thread#1 (ParallelGC)" prio=10 tid=0x083d4000 nid=0x57be runnable
22463 0 8.0 "GC task thread#2 (ParallelGC)" prio=10 tid=0x083d5800 nid=0x57bf runnable
22464 0 8.0 "GC task thread#3 (ParallelGC)" prio=10 tid=0x083d7000 nid=0x57c0 runnable
...
次に、/ tmp / jstack.logに戻って、問題のあるスレッドのスタックトレースを調べ、そこから何が起こっているのかを理解しようとします。もちろん、このソリューションはプラットフォームに依存しますが、* nixのほとんどのフレーバーと、あちこちで微調整することで機能するはずです。
CPU 使用率順に Java スレッドを視覚化するための top のようなコマンドを作成し、ソース コードをhttps://github.com/jasta/jprocpsに投稿しました。コマンドライン構文は top ほど豊富ではありませんが、同じコマンドのいくつかをサポートしています。
$ jtop -n 1
サンプル出力 (実行中の ant と IntelliJ を表示):
PID TID USER %CPU %MEM THREAD
13480 13483 jasta 104 2.3 main
13480 13497 jasta 86.3 2.3 C2 CompilerThread1
13480 13496 jasta 83.0 2.3 C2 CompilerThread0
4866 4953 jasta 1.0 13.4 AWT-EventQueue-1 12.1.4#IC-129.713, eap:false
4866 14154 jasta 0.9 13.4 ApplicationImpl pooled thread 36
4866 5219 jasta 0.8 13.4 JobScheduler pool 5/8
この出力から、スレッドのスタック トレースをjconsole手動jstackで取得して、何が起こっているかを把握できます。
注: jtopは Python で記述されており、jstackインストールする必要があります。
jstackがJDK 8の時点で古くなっていることがわかった限り。すべてのJavaスレッド名を取得するために使用したのは次のとおりです。
<JDK_HOME>/bin/jcmd <PID> Thread.print
詳細については、 jcmd のドキュメントを確認してください。
カーネルに関する限り、スレッドには名前がありません。ID番号しかありません。JVMはスレッドに名前を割り当てますが、これはプロセス内のプライベート内部データであり、「トップ」プログラムはアクセスできません(とにかくそれについては知りません)。