Как jstack -F влияет на работающий процесс Java?

Я пытаюсь диагностировать проблему, когда веб-приложение Java, которое я использую (Jenkins), перестает отвечать на запросы. Если я бегу jstack без -F флаг это ничего мне не дает, но если я установлю флаг, чтобы вызвать дамп потока, я не только получу результат, но приложение начнет отвечать и работать так, как будто ничего не произошло, пока в конечном итоге перестанет отвечать снова.

Что значит jstack -F Отметьте, что может повлиять на работающую JVM и привести к тому, что неотвечающее приложение снова начнет отвечать?

2 ответа

Вы можете увидеть источник jstack здесь. Аргумент -F изменяет способ соединения jstack с jvm. С помощью -F (или -m) JStack подключается к jvm с помощью интерфейса отладчика java. Если указан 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 (<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 -> 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 в целевом процессе. если ваше приложение зависло из-за истощения потока, вызов метода suspend может ослабить их.

Другие вопросы по тегам