jstack-F如何影响正在运行的Java进程?
我试图诊断一个我正在使用的Java web应用程序(Jenkins)没有响应的问题。如果我在没有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
-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.");
}