Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

Вы можете увидеть источник в jstack здесь. Аргумент -F изменяет способ подключения jstm к jvm. С -F (или -m) JStack подключается к jvm с помощью интерфейса java debugger. Если указан pid, JStack соединяется с SA PID Attaching Connector, который гласит:

Отлаживаемый процесс не должен запускаться в отладке (т.е. с -agentlib: jdwp или -Xrunjdwp). Это допустимо для > .

Я не знаю, почему это приведет к тому, что невосприимчивое приложение начнет отвечать на запросы снова, но ссылка выше также говорит:

Процесс приостанавливается, когда этот соединитель присоединяется и возобновляется, когда этот разъем отсоединяется.

Это может иметь эффект.

Ответ 2

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

а так как -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 method

Возможно, ниже кода магия

       jvmdi = new ServiceabilityAgentJVMDIModule(debugger, saLibNames);
       if (jvmdi.canAttach()) {
           jvmdi.attach();
           jvmdi.setCommandTimeout(6000);
           debugPrintln("Attached to Serviceability Agent JVMDI module.");
           // Jog VM to suspended point with JVMDI module
           resume();
           suspendJava();
           suspend();
           debugPrintln("Suspended all Java threads.");
       }

он приостанавливает все потоки Java в целевом процессе. если ваше приложение зависает для голодания нити, вызов метода suspend может ослабить их.