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

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

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

你可以在这里看到j​​stack的来源。 -F参数更改jstack连接到jvm的方式。 使用-F(或-m)JStack使用java调试器接口连接到jvm。 如果指定了pid,JStack将连接SA PID附加连接器 ,该连接器表示,

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

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

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

这可能会产生影响。

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