Как 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 может ослабить их.