предисловие
Если в один прекрасный день ваша Java-программа остановится надолго, может быть, она больна, вам нужно использовать jstack, чтобы взять фильм для анализа и анализа, чтобы диагностировать конкретную болезнь, будь то синдром взаимоблокировки или бесконечный цикл и другие заболевания, мы соберемся в этой статье Изучите команду jstack~
- Особенности jstack
- использование jstack
- Базовый обзор состояния потока и т. д.
- Практический случай 1: взаимоблокировка анализа jstack
- Практический случай 2: jstack анализирует, что ЦП слишком высок
Особенности jstack
jstack — это инструмент трассировки стека Java, который поставляется с JVM и используется для вывода информации о стеке Java для заданного идентификатора процесса Java, основного файла и службы удаленной отладки.
jstack prints Java stack traces of Java threads for a given Java process or
core file or a remote debug server.
- Команда jstack используется для создания снимка потока текущего момента виртуальной машины.
- Моментальный снимок потока — это набор стеков методов, которые выполняются каждым потоком на текущей виртуальной машине.Основная цель создания снимка потока — найти причину длительной паузы потока. Например, взаимоблокировка между потоками, бесконечный цикл, длительное ожидание, вызванное запросом внешних ресурсов и т. д.
- Когда поток приостановлен, вы можете просмотреть стек вызовов каждого потока через jstack и узнать, что не отвечающий поток делает в фоновом режиме или какие ресурсы он ожидает.
- Если программа Java дает сбой при создании основного файла, можно использовать инструмент jstack для получения информации о стеке Java и собственном стеке основного файла, чтобы вы могли легко узнать, как происходит сбой программы Java и где возникает проблема. программа.
- Кроме того, инструмент jstack также можно подключить к работающей Java-программе, чтобы просмотреть информацию о стеке Java и собственном стеке работающей Java-программы в это время. очень полезно.
использование jstack
Формат команды jstack следующий:
jstack [ option ] pid
jstack [ option ] executable core
jstack [ option ] [server-id@]remote-hostname-or-IP
- исполняемый исполняемый файл Java, из которого был создан дамп памяти (может быть исполняемой программой Java, которая создала дамп ядра).
- core Файл дампа ядра, в котором будет напечатана информация
- remote-hostname-or-IP Имя хоста или IP-адрес службы удаленной отладки.
- server-id уникальный идентификатор, если на одном хосте есть несколько удаленных служб отладки
Наиболее часто используются
jstack [option] <pid> // 打印某个进程的堆栈信息
Описание параметра options выглядит следующим образом:
Опции | эффект |
---|---|
-F | Принудительный выходной стек потока, когда запрос не отвечает без ответа |
-m | Если вызывается собственный метод, может отображаться стек C/C++. |
-l | В дополнение к стеку отображается дополнительная информация о блокировке.В случае взаимоблокировки вы можете использовать jstack -l pid для наблюдения за состоянием удержания блокировки. |
Базовый обзор состояния потока и т. д.
Введение в состояние потока
jstack используется для создания моментальных снимков потока. Мы анализируем ситуацию в потоке. Нам нужно просмотреть статус потока. Возьмите небольшой табурет, сядьте и просмотрите его~
Язык Java определяет шесть состояний пула потоков:
- Новое: потоки, которые не были запущены после создания, находятся в этом состоянии и не будут отображаться в дампе.
- РАБОТАЕТ: включая «Работает» и «Готово». Когда поток запускает метод start(), он переходит в это состояние и выполняет его на виртуальной машине.
- Ожидание: бесконечное ожидание определенной операции другого потока.
- Ожидание по времени: ограниченное по времени ожидание определенной операции другого потока.
- Заблокировано: когда программа ожидает входа в область синхронизации, поток переходит в это состояние, ожидая блокировки монитора.
- Завершено: состояние завершенного потока, выполнение потока завершено.
Состояние потока файла дампа обычно бывает следующих трех типов:
- RUNNABLE, поток выполняется
- ЗАБЛОКИРОВАН, тема заблокирована
- WAITING, нить ждет
Блокировка монитора монитора
Поскольку Java-программы обычно выполняются в нескольких потоках, многопоточность Java тесно связана с отслеживанием блокировок, поэтому при анализе состояния потока нам также необходимо проверять знания о мониторинге блокировок.
Существует взаимосвязь любви и ненависти между ключевым словом синхронизации потоков Synchronized и блокировками мониторинга.Заинтересованные партнеры могут прочитать мою статью.Синхронный анализ - если вы готовы чистить мое сердце слой за слоем
Принцип работы монитора заключается в следующем:
- Если поток хочет получить монитор, он сначала войдет в очередь набора записей, которая является ожидающим потоком, а состояние потока — ожидание записи монитора.
- Когда поток успешно получает монитор объекта и входит в область владельца, это активный поток.
- Если поток вызывает метод wait(), он войдет в очередь Wait Set, он снимет блокировку монитора, которая также является Ожидающим потоком, состоянием потока в Object.wait()
- Если другой поток вызывает notify() / notifyAll() , он разбудит поток в наборе ожидания, поток снова попытается получить блокировку монитора и в случае успеха войдет в область владельца.
Фокус анализа файла дампа
- runnable, поток выполняется
- тупик, тупик (сосредоточиться)
- заблокирован, поток заблокирован (фокус на)
- Припарковался, остановись
- заблокирован, объект заблокирован
- ждёт, тред ждёт
- ожидание блокировки
- Object.wait(), ожидающий объект
- ожидание записи монитора
- Ожидание по условию, ожидание ресурсов (фокус на), наиболее распространенная ситуация заключается в том, что поток ожидает, пока сеть прочитает и запишет
Практический пример 1: jstack анализирует проблему взаимной блокировки
- Что такое тупик?
- Как использовать jstack для устранения взаимоблокировок?
Что такое тупик?
Тупик относится к явлению, при котором два или более потока ожидают друг друга из-за конкуренции за ресурсы в процессе выполнения, и если нет внешней силы, они не смогут продолжить работу.
Как использовать, как использовать jstack для устранения неполадок взаимоблокировки
Давайте сначала посмотрим на программу Java, которая вызовет взаимоблокировку.Исходный код выглядит следующим образом:
/**
* Java 死锁demo
*/
public class DeathLockTest {
private static Lock lock1 = new ReentrantLock();
private static Lock lock2 = new ReentrantLock();
public static void deathLock() {
Thread t1 = new Thread() {
@Override
public void run() {
try {
lock1.lock();
System.out.println(Thread.currentThread().getName() + " get the lock1");
Thread.sleep(1000);
lock2.lock();
System.out.println(Thread.currentThread().getName() + " get the lock2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t2 = new Thread() {
@Override
public void run() {
try {
lock2.lock();
System.out.println(Thread.currentThread().getName() + " get the lock2");
Thread.sleep(1000);
lock1.lock();
System.out.println(Thread.currentThread().getName() + " get the lock1");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
//设置线程名字,方便分析堆栈信息
t1.setName("mythread-jay");
t2.setName("mythread-tianluo");
t1.start();
t2.start();
}
public static void main(String[] args) {
deathLock();
}
}
результат операции:
Очевидно, поток jay и поток tianluo выполнены только наполовину и застряли в блокирующем состоянии ожидания~jstack шаги по устранению неполадок в Java
- Введите jsp в терминал, чтобы просмотреть текущую запущенную программу Java.
- Используйте jstack -l pid для просмотра информации о стеке потоков.
- Анализировать информацию о стеке
Введите jsp в терминал, чтобы просмотреть текущую запущенную программу Java.
Используя команду jps для получения pid процесса, который необходимо отслеживать, мы обнаружили23780 DeathLockTest
Используйте jstack -l pid для просмотра информации о стеке потоков.
Из приведенного выше рисунка хорошо видно, чтотупикИнформация:- myread-tianluo ожидает эту блокировку «0x00000000d61ae3a0», которая удерживается потоком myread-jay.
- Поток myread-jay ожидает блокировки «0x00000000d61ae3d0», которую удерживает поток myread-tianluo.
Восстановить правду о тупике
Анализ информации о стеке потока «mythread-tianluo» выглядит следующим образом:- Нить myread-tianluo находится в состоянии ожидания, удерживая блокировку «0x00000000d61ae3d0», ожидая блокировки «0x00000000d61ae3a0».
Анализ информации о стеке потока «mythread-jay» выглядит следующим образом:
- Нить myread-tianluo находится в состоянии ожидания, удерживая блокировку «0x00000000d61ae3a0», ожидая блокировки «0x00000000d61ae3d0».
Практический пример 2: jstack анализирует проблему высокой загрузки процессора
Приходите к демонстрационной программе, которая заставляет ЦП слишком сильно загружаться, бесконечный цикл, ха-ха~
/**
* 有个导致CPU过高程序的demo,死循环
*/
public class JstackCase {
private static ExecutorService executorService = Executors.newFixedThreadPool(5);
public static void main(String[] args) {
Task task1 = new Task();
Task task2 = new Task();
executorService.execute(task1);
executorService.execute(task2);
}
public static Object lock = new Object();
static class Task implements Runnable{
public void run() {
synchronized (lock){
long sum = 0L;
while (true){
sum += 1;
}
}
}
}
}
jstack анализ высоких шагов процессора
-
- top
-
- top -Hp pid
-
- jstack pid
-
- jstack -l [PID] >/tmp/log.txt
-
- Анализировать информацию о стеке
1.top
На сервере мы можем просмотреть использование процессора каждым процессом с помощью верхней команды, которая по умолчанию отсортирована по использованию процессора от высокого к низкому.
Из приведенного выше рисунка мы можем узнать, что java-процесс с pid 21340 занимает больше всего ресурсов процессора и является убийцей, ха-ха!2. top -Hp pid
Через top-Hp 21340 вы можете просмотреть использование процессора каждым потоком в рамках процесса следующим образом:
Можно обнаружить, что поток с pid 21350 имеет самое высокое использование ресурсов процессора~, хе-хе, я записал это в небольшой блокнот, а затем взял jstack, чтобы снять это~3. jstack pid
После обнаружения потока с высокой загрузкой ЦП с помощью команды top используйте команду jstack pid для просмотра состояния стека текущего процесса Java.jstack 21350
После этого содержание следующее:
4. jstack -l [PID] >/tmp/log.txt
На самом деле на первых 3-х шагах вылезла информация о стеке. Но обычно в среде генерации мы можем ввести эту информацию о стеке в файл, а затем вернуться и тщательно проанализировать ее~
5. Анализируйте информацию о стеке
Мы конвертируем pid потока, занимающего большие ресурсы ЦП (в данном примере 21350), в шестнадцатеричное значение.
В THREAD DUMP у каждого потока есть NID, находим соответствующий NID (5366), нашли, что он запущен (24 строки)В это время вы можете проверить, есть ли какие-либо проблемы с кодом~ Конечно, также рекомендуется время от времени снова выполнять команду стека, а затем снова получать дамп потока.В конце концов, сравнение два результата съемки (jstack) более точны~
Ссылка и спасибо
- jstack, инструмент настройки производительности jvm
- Как анализировать статус потока с помощью jstack
- Серия по изучению команд Java (2) — Jstack
Личный публичный аккаунт
- Если вы считаете, что это хорошо написано, пожалуйста, поставьте лайк + подпишитесь, спасибо~
- Если что-то не так, укажите на это, большое спасибо.
- В то же время, я очень жду, что мои друзья обратят внимание на мой официальный аккаунт, и позже я постепенно представлю более качественные галантерейные товары~ хи хи
- адрес гитхаба:GitHub.com/Я бы хотел 123/Java…