32

使用している Java Web アプリケーション (Jenkins) が応答しなくなる問題を診断しようとしています。jstackフラグなしで実行-Fしても何も得られませんが、スレッド ダンプを強制するためにフラグを入れると、結果が得られるだけでなく、アプリケーションが応答を開始し、最終的には何も起こらなかったかのように続行します。再び応答を停止します。

jstack -F実行中の JVM に影響を与え、応答しないアプリケーションが再び応答を開始する原因となる flag の機能は何ですか?

4

2 に答える 2

16

ここでjstackのソースを確認できます。-F引数は、jstackがjvmに接続する方法を変更します。-F(または-m)を使用すると、JStackはJavaデバッガーインターフェイスを使用してjvmに接続します。pidが指定されている場合、JStackはSAPID接続コネクタに接続します。

デバッグするプロセスは、デバッグモードで開始されている必要はありません(つまり、-agentlib:jdwpまたは-Xrunjdwpを使用)。プロセスがハングすることは許容されます。

応答しないアプリケーションが再び応答を開始する理由はわかりませんが、上記のリンクには、

このコネクタが接続されるとプロセスが一時停止され、このコネクタが切断されるとプロセスが再開されます。

これは影響を与える可能性があります。

于 2012-08-26T14:44:07.750 に答える
11

jstack -F -l pid は (作業ディレクトリが JAVA_HOME であると仮定) と同様です。

bin/java -Dsun.jvm.hotspot.debugger.useWindbgDebugger  -Dsun.jvm.hotspot.debugger.useProcDebugger  -cp lib/sa-jdi.jar;lib/tools.jar  sun.tools.jstack.JStack -F -l pid

およびsun.tools.jstack.JStack コード内

   if (arg.equals("-F")) {
       useSA = true;
   }
   .....
   // now execute using the SA JStack tool or the built-in thread dumper
   if (useSA) {
       // parameters (<pid> or <exe> <core>
       ...
       runJStackTool(mixed, locks, params);
   } else {
       // pass -l to thread dump operation to get extra lock info
       String pid = args[optionCount];
        ...
       runThreadDump(pid, params);
    }

-F が渡されるため、runJStackTool が呼び出されて、sun.jvm.hotspot.tools.JStack がロードされます。直接呼び出すのと同じ効果があります。

bin\java -Dsun.jvm.hotspot.debugger.useWindbgDebugger  -Dsun.jvm.hotspot.debugger.useProcDebugger  -cp lib/sa-jdi.jar;lib/tools.jar  sun.jvm.hotspot.tools.JStack pid

そして、sun.jvm.hotspot.tools.JStack は、sun.jvm.hotspot.bugspot.BugSpotAgent を呼び出しますattach -> go ->setupVM メソッド

多分以下のコードは魔法です

       jvmdi = new ServiceabilityAgentJVMDIModule(debugger, saLibNames);
       if (jvmdi.canAttach()) {
           jvmdi.attach();
           jvmdi.setCommandTimeout(6000);
           debugPrintln("Attached to Serviceability Agent's JVMDI module.");
           // Jog VM to suspended point with JVMDI module
           resume();
           suspendJava();
           suspend();
           debugPrintln("Suspended all Java threads.");
       }

ターゲット プロセスのすべての Java スレッドを中断します。アプリケーションがスレッド スタベーションのためにハングしている場合、suspend メソッドの呼び出しによってスレッドが緩和されることがあります。

于 2012-08-29T13:34:30.840 に答える