How does jstack -F affect a running Java process?

我与影子孤独终老i 提交于 2019-11-29 10:48:47

问题


I am trying to diagnose a problem where a Java web application I'm using (Jenkins) becomes unresponsive. If I run jstack without the -F flag it doesn't give me anything, but if I put the flag in to force a thread dump not only do I get a result, but the application starts responding and goes on as if nothing had happened until it eventually stops responding again.

What does jstack -F flag do that would affect a running JVM and cause an unresponsive application to start responding again?


回答1:


You can see the source to jstack here. The -F argument changes how jstack connects to the jvm. With -F (or -m) JStack connects to the jvm using the java debugger interface. If a pid is specified, JStack connects with the SA PID Attaching Connector which says,

The process to be debugged need not have been started in debug mode(ie, with -agentlib:jdwp or -Xrunjdwp). It is permissable for the process to be hung.

I don't know why it would cause an unresponsive application to start responding again, but the link above also says,

The process is suspended when this connector attaches and resumed when this connector detaches.

This may have an effect.




回答2:


jstack -F -l pid is similarly to (assume working dir is 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

and in the 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);
    }

and since -F is passed in, runJStackTool is called to load sun.jvm.hotspot.tools.JStack, it have same effect of invoking directly

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

and sun.jvm.hotspot.tools.JStack will call sun.jvm.hotspot.bugspot.BugSpotAgent attach -> go ->setupVM method

Maybe below code is the magic

       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.");
       }

it will suspend all Java threads in the target process. if your application is hang for thread starvation, the suspend method call may relax them.



来源:https://stackoverflow.com/questions/12061226/how-does-jstack-f-affect-a-running-java-process

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!