17

最も負荷の高い実稼働インストールでは、無限ループに陥ったように見える単一のスレッドが発生することがあります。多くの調査とデバッグを行った後、犯人が誰であるかを突き止めることはできませんでしたが、それは可能であるように思われます. 悲惨な詳細は次のとおりです。

現在のデバッグに関する注意事項:

1) ps -eL 18975は、問題の子スレッドである Linux pid 19269 を表示します。

$ps -eL | grep 18975
...
PID   LWP   TTY          TIME CMD
18975 18994 ?        00:00:05 java
18975 19268 ?        00:00:00 java
18975 19269 ?        05:16:49 java
18975 19271 ?        00:01:22 java
18975 19273 ?        00:00:00 java
...

2) jstack -l 18975はデッドロックがないことを示し、jstack -m 18975は機能しません

3) jstack -l 18975は、すべてのスレッド (~400) のスタック トレースを提供します。スレッド スタックの例 (問題ではありません):

"http-342.877.573.944-8080-360" デーモン prio=10 tid=0x0000002adaba9c00 nid=0x754c in Object.wait() [0x00000000595bc000..0x00000000595bccb0]
   java.lang.Thread.State: WAITING (オブジェクトモニター上)
        at java.lang.Object.wait(ネイティブメソッド)
        - 待機中 (org.apache.tomcat.util.net.JIoEndpoint$Worker)
        java.lang.Object.wait(Object.java:485) で
        org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:416) で
        - ロック済み (org.apache.tomcat.util.net.JIoEndpoint$Worker)
        org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:442) で
        java.lang.Thread.run(Thread.java:619) で

4) ps -eL 出力のスレッド ID が jstack からの出力と一致しないか、少なくとも表示できません。(jstack のドキュメントは少しまばらです。)

5) 大量の IO、メモリ使用量、または対応するその他の対応するアクティビティの手がかりはありません。

プラットホーム:

  • Java 6
  • トムキャット6
  • RHEL 4 (64 ビット)

Linux ps 出力から問題の子 Java スレッドに接続する方法を知っている人はいますか? こんなに近くて、まだ遠い…

4

5 に答える 5

13

jstack 出力のnidは Linux LWP id のようです。

"http-342.877.573.944-8080-360" daemon prio=10 tid=0x0000002adaba9c00 nid=0x754c in Object.wait() [0x00000000595bc000..0x00000000595bccb0]

nid を 10 進数に変換すると、LWP id が得られます。あなたの場合、0x754c は 30028 です。このプロセスは ps 出力には示されていませんが、スペースを節約するために省略した LWP の 1 つだった可能性があります。

これは、jstack の出力をパイプするために使用できる小さな Perl スニペットです。

#!/usr/bin/perl -w
while (<>) {
    if (/nid=(0x[[:xdigit:]]+)/) {
        $lwp = hex($1);
        s/nid=/lwp=$lwp nid=/;
    }
    print;
}
于 2009-07-29T09:53:04.977 に答える
7

JConsoleを使用して、スレッドのスタック トレースを表示できます。

JDK 1.6.0_07 以降を使用している場合は、visualvmも使用できます。

どちらのツールも、アプリケーションで実行中のすべてのスレッドの優れたビューを提供します。visualvm の方がかなり優れていますが、すべてのスレッドを確認することで、暴走したスレッドを追跡するのに役立つことを願っています。

常にRUNNING 状態のスレッドをチェックします。ランナウェイ スレッドが発生した場合、スタック トレースは常に変化していました。そのため、ループが呼び出しているメソッドを特定し、ループを追跡することができました。

于 2008-10-21T14:47:20.823 に答える
1

いい、役に立つ答え!

Linux の場合、ps -efL を使用します。-L オプションは LWP を表示します。ちなみに、
"http-342.877.573.944-8080-360" デーモン prio=10は、" ThreadName (JVM によって指定されたもの)" runningmode (pid から継承)優先度( pid から継承) を意味します。

于 2012-03-30T14:03:14.900 に答える
0

コンソールで CTRL-BREAK を実行すると、現在のスレッドのダンプといくつかのスタック トレース フレームがメモリから取得されます。

メモリから(これがIntelliJ IDEaの機能なのか、Javaのデフォルトなのかはわかりません)、どのスレッドがデッドロックされているか、どのオブジェクトが待機しているかがわかります。出力をファイルにリダイレクトし、DEADLOCKED テキストを grep するだけでよいはずです。

JConsole、VisualVM、または JProfiler などの他のプロファイラーでもスレッドとそのスタックが表示されますが、外部ツールを使用したくない場合は、CTRL-BREAK で探しているものが得られると思います。

于 2008-10-22T03:31:14.043 に答える
0

日曜日に

prstatデフォルトでは、LWPID ではなく軽量プロセスの数が表示されることに注意してください。

特定のユーザーのすべての軽量プロセスの情報を表示するには、-Lオプションを使用します。

prstat -L -v -u weblogic

LWPID を使用して 16 進数に変換し、スレッド ダンプの nid と一致させます。

于 2009-11-25T16:13:59.833 に答える