jstack -F如何影响正在运行的Java进程?

时间:2012-08-21 18:53:18

标签: java jvm jstack

我正在尝试诊断我正在使用的Java Web应用程序(Jenkins)无法响应的问题。如果我在没有jstack标志的情况下运行-F它没有给我任何东西,但是如果我将标志放入以强制进行线程转储,不仅我得到了结果,而且应用程序开始响应并且继续,好像什么也没发生,直到它最终再次停止响应。

jstack -F标志会影响正在运行的JVM并导致无响应的应用程序再次开始响应?

2 个答案:

答案 0 :(得分:15)

您可以看到jstack here的来源。 -F参数更改jstack连接到jvm的方式。使用-F(或-m)JStack使用java调试器接口连接到jvm。如果指定了pid,则JStack将与SA PID Attaching Connector连接,后者表示

  

无需在调试中启动要调试的进程   模式(即使用-agentlib:jdwp或-Xrunjdwp)。它是允许的   进程挂起

我不知道为什么它会导致无响应的应用程序再次开始响应,但上面的链接也说明了,

  

当此连接器连接时,该过程暂停,并在此时恢复   这个连接器分离。

这可能会产生影响。

答案 1 :(得分: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 code

   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 - &gt; go - &gt; 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线程。如果您的应用程序因线程饥饿而挂起,则挂起方法调用可能会放松它们。