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

jstack-F如何影响正在运行的Java进程?,java,jvm,jstack,Java,Jvm,Jstack,我试图诊断一个我正在使用的Java web应用程序(Jenkins)没有响应的问题。如果我在没有-F标志的情况下运行jstack,它不会给我任何东西,但是如果我使用该标志强制线程转储,不仅会得到一个结果,而且应用程序会开始响应,就像什么都没有发生一样,直到它最终停止响应 jstack-F标志做了什么会影响正在运行的JVM并导致无响应的应用程序再次开始响应?您可以看到jstack的源代码。-F参数更改jstack连接到jvm的方式。使用-F(或-m),JStack使用java调试器接口连接到jvm

我试图诊断一个我正在使用的Java web应用程序(Jenkins)没有响应的问题。如果我在没有
-F
标志的情况下运行
jstack
,它不会给我任何东西,但是如果我使用该标志强制线程转储,不仅会得到一个结果,而且应用程序会开始响应,就像什么都没有发生一样,直到它最终停止响应


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

您可以看到jstack的源代码。-F参数更改jstack连接到jvm的方式。使用-F(或-m),JStack使用java调试器接口连接到jvm。若指定了一个pid,JStack将连接到

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

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

连接此连接器时,进程将暂停;连接后,进程将继续 此连接器可分离


这可能会产生影响。

jstack-F-lpid类似于(假设工作目录是JAVA\u HOME)

sun.jvm.hotspot.tools.JStack将调用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线程。如果应用程序因线程不足而挂起,则挂起方法调用可能会使其放松。

只是猜测,但它可能会导致虚假唤醒或类似情况发生。为了确定问题的原因,我将尝试使用jdb。通过这种方式,当应用程序没有响应时,您将能够附加并调查原因。PID附加机制不要求被检查的进程协作—它只检查内存结构并尝试找出可用的内存。它提供的信息可能比友好地询问时少。好吧,我已经理解了为什么在jstack-F之后它可以更好地工作。进程暂停并唤醒后会发生什么变化,从而导致应用程序再次响应?@JordanBentley如果不知道应用程序为什么没有响应,很难知道为什么。是gc'ing,调出,机器本身过载吗?@sbridges大多数时候,当我在机器上运行jmap-heap时,当它没有响应时,它将显示eden空间已满,所以我假设gc正在进行。我打开了并发GC,但这没有任何区别。这台机器不可能过载,它是一台功能强大的服务器,除了Jenkins之外没有其他任何东西在上面运行,当它没有运行任何构建时,问题仍然会发生。我的下一步将是尝试一个不同的JVM,但出于我自己的好奇心,我仍然想知道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);
    }
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
       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.");
       }