Jstack снять дамп linux

Обновлено: 02.07.2024

вы можете также использовать jstack (входит в комплект JDK), чтобы взять дамп потока и записать вывод везде, где вы хотите. Это не доступно в среде Unix?

дамп потока записывается в систему из виртуальной машины, на которой вы выполнили убийство -3. Если вы перенаправляете консольный вывод JVM в файл, дамп потока будет находиться в этом файле. Если JVM работает в открытой консоли, то дамп потока будет отображаться в консоли.

С Java 8 на рисунке, jcmd предпочтительный подход.

Ниже приведен фрагмент документация Oracle:

выпуск JDK 8 представил Java Mission Control, Java Flight Recorder и утилиту jcmd для диагностики проблем с приложениями JVM и Java. предлагается использовать последнюю утилиту jcmd вместо предыдущей утилиты jstack для улучшенной диагностики и снижения производительности накладные расходы.

однако доставка этого с приложением может иметь последствия лицензирования, которые я не уверен.

в том же месте, где находится stdout JVM. Если у вас есть сервер Tomcat, это будет .

  • Kill -3: дает выход к стандартному выходу.
  • Если у вас есть доступ к окну консоли, где работает сервер, можно использовать комбинацию клавиш Ctrl + Break для создания трассировки стека на std выход.
  • для виртуальной точки доступа мы можем использовать команду jstack, чтобы генерировать дамп потока. Это часть JDK. Синтаксис выглядит следующим образом: Использование: jstack [- l] (для подключения к запущенному процессу) jstack-F [- m] [- l] (для подключения к зависшему процессу)
  • для виртуальная машина JRockit JVM в мы можем использовать команду JRCMD, который поставляется с JDK для синтаксис: jrcmd [ []] [л] [-F файл] [-р] -ч]

в Jboss вы можете выполнить следующее

это перенаправит ваш вывод / threadump в файловую консоль, указанную в приведенной выше команде.

  1. найти идентификатор процесса [PS ID]
  2. выполнить поток jcmd [PS ID].печати

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

Шаг 1: получить идентификатор процесса для сценария оболочки, вызывающего программу java

Шаг 2: получить идентификатор процесса для дочернего элемента, который был вызван runABCD. Используйте выше PID, чтобы получить детей.

Шаг 3: получить JSTACK для конкретного процесса. Получите идентификатор процесса вашего XYSServer процесс. т. е. 8536

Иногда возникают ситуации, при которых JIRA может «зависнуть» во время выполнения операции. В течение этого времени полезно получить дамп потока - журнал, содержащий информацию о текущих выполняемых потоках и процессах в виртуальной машине Java. Взятие дампов-потоков - это неразрушающий процесс, который можно запускать во время работающей системы JIRA. В рассматриваемых ниже инструкциях пользователю описаны шаги, необходимые для получения дампа- потока в различных используемых операционных системах JIRA .

Шаги, необходимые для получения дампа- потока, зависят от операционной системы JIRA и выполняются в соответствии с приведенными ниже инструкциями.

Среда Windows

JIRA работает от startup.bat

  1. В окне командной консоли (Command Console), где запущена JIRA, откройте диалоговое окно свойств, щелкнув правой кнопкой мыши на строке заголовка и выберите «Свойства» (Properties).
  2. Выберите вкладку «Макет» (Layout).
  3. В разделе «Размер буфера экрана» (Screen Buffer Size) установите значение «Высота» (Height) на «3000».


  1. Нажмите «ОК».
  2. С той же командной консоли в фокусе нажмите CTRL-BREAK. Это выведет дамп потока в консоль.
  3. Выполните прокрутку назад в командной консоли, пока не достигнете строки, содержащей «Полный дамп потока».
  4. Щелкните правой кнопкой мыши строку заголовка и выберите «Редактировать» (Edit)> «Отметить» (Mark). Выделите весь текст дампа потока.
  5. Щелкните правой кнопкой мыши строку заголовка и выберите «Правка» (Edit )> «Копировать» (Copy). Затем дамп потока можно вставить в текстовый файл.


JIRA работает как служба Windows

Использование jstack

JDK поставляется с инструментом jstack для создания дампов - потоков.

  1. Определите процесс. Запустите диспетчер задач, нажав Ctrl + Shift + Esc и найдите идентификатор процесса Java (JIRA). Вам может понадобиться добавить столбец PID с помощью View -> Select Columns .
  2. Запустите jstack <pid>, чтобы захватить одиночный дамп потока. Эта команда примет один дамп потока идентификатора процесса <pid>, в этом случае pid равен 22668:

Это выведет файл с именем threaddump.txt в ваш текущий каталог.

Общие проблемы с jstack:

psexec -s jstack <pid> >> threaddumps.txt

  • Если исполняемый файл jstack не находится в вашем $ PATH, то, пожалуйста, найдите его в каталоге <JDK_HOME> / bin
  • Если вы получаете java.lang.NoClassDefFoundError: sun / tools / jstack / JStack, проверьте, что tools.jar присутствует в вашем каталоге lib JDK. Если это не так, загрузите полную версию JDK.

Окружающая среда Linux / Unix / OS X

Использование jstack и top

См. «Устранение неполадок производительности задач» с помощью дампов потоков для сочетания как верхнего, так и jstack, чтобы обеспечить вывод отдельных потоков центрального процессора вместе со своей трассировкой стека.

Альтернатива Linux / Unix: Командная строка

  1. Определите java-процесс, в котором работает JIRA. Этого можно добиться, выполнив команду, аналогичную:

Процесс будет выглядеть следующим образом:

  1. Чтобы получить дамп потока, выполните команду

где pid - это идентификатор процесса - в этом случае 910.

  1. Дамп потока будет записан на вывод консоли Tomcat. Консольный вывод перенаправляется в файл logs / catalina.out, который можно найти в каталоге установки JIRA для автономного / установщика JIRA или для JIRA WAR в каталоге установки Tomcat

Альтернатива Linux / Unix: создание дампов потоков с использованием jstack

Если у вас возникли проблемы с использованием kill -3 <pid> для получения дампа- потока, попробуйте использовать jstack утилиту java, которая будет выводить трассировки стека потоков Java для данного процесса.

  1. Определите javaprocess, в котором работает JIRA. Этого можно добиться, выполнив команду, аналогичную:
  1. Процесс будет выглядеть следующим образом:
  1. Запустите jstack <pid> для захвата одиночного дампа потока

Эта команда возьмет один дамп потока id процесса <pid>, в этом случае pid будет 22668 и выведет на выход в файл JIRAthreaddump.txt

Как правило, вы захотите взять несколько дампов на временном интервале около 10 секунд. В этом случае вы можете создать несколько дампов и вывести трассировки стека в один файл следующим образом:

Если вы подключаетесь к серверу через RDP, jstack может завершиться сбоем со следующей ошибкой:

Вам нужно будет открыть сеанс RDP в консольном режиме: mstsc / admin

Инструменты анализа

Попробуйте TDA или Samurai проверить ваш дамп потока.

  1. Скачайте TDA.
  2. Смените каталог, где существует JAR.
  3. Запустите:

Откройте файл catalina.out, содержащий дамп потока

Дамп потока обработки задачи с помощью TDA (NumberFormatException)

sed -i 's / prio = 7 \ os_prio = 4 \ / prio = 5 / g' <имя_файла>

sed -i '' 's/prio=6\ os_prio=7\/prio=5/g' <filename>

В этом учебнике мы обсудим различные способы захвата свалки потоков java-приложения.

Дампа потока является моментальным снимком состояния всех потоков процесса Java, . Состояние каждого потока представлено следом стека, показывающим содержимое стека потока. Дампа потока полезна для диагностики проблем при отображении активности потока. Свалки потоков написаны простым текстом, поэтому мы можем сохранить их содержимое в файле и посмотреть на них позже в текстовом редакторе .

В следующих разделах мы пройдемся по нескольким инструментам и подходам для создания свалки потоков.

2. Использование утилит JDK

JDK предоставляет несколько утилит, которые могут захватить свалку потока java-приложения. Все коммунальные услуги расположены под бен папка внутри домашнего каталога JDK . Таким образом, мы можем выполнять эти утилиты из командной строки до тех пор, пока этот каталог находится на нашем системного пути.

2.1. jstack

Давайте рассмотрим основной синтаксис команды для захвата свалки потоков с помощью jstack:

Все флаги не являются обязательными. Давайте посмотрим, что они означают:

  • -F опция заставляет дампа потока; удобно использовать при jstack pid не отвечает (процесс завис)
  • -l опция поручает утилите искать собственные синхронизаторы в куче и замки
  • -m вариант печатает кадры из родных стеков (C и C) в дополнение к рамкам стеков Java

Давайте будем использовать эти знания, захватив дампа потока и перенаправив результат в файл:

Помните, что мы можем легко получить пид Java-процесса с помощью JPS команда.

2.2. Управление полетами Java

Java Управление полетами (JMC) — это инструмент gui, который собирает и анализирует данные из Java-приложений. После запуска JMC отображается список java-процессов, работающих на локальной машине. Мы также можем подключиться к удаленным Java-процессам через JMC.

2.3. jvisualvm

jvisualvm это инструмент с графическим пользовательским интерфейсом, который позволяет нам отслеживать, устранения неполадок и профиля Java приложений . Графический интерфейс прост, но очень интуитивно понятен и прост в использовании.

По данный раз JDK 9 Visual VM не входит в дистрибутивы Oracle JDK и Open JDK. Поэтому, если мы используем Java 9 или более новые версии, мы можем получить JVisualVM от Visual VM с открытым исходным кодом сайт проекта .

2.4. jcmd

jcmd это инструмент, который работает, отправляя командные запросы в JVM. Хотя мощный, он не содержит удаленной функциональности – мы должны использовать его в той же машине, где работает процесс Java.

Одна из его многочисленных команд Thread.print . Мы можем использовать его, чтобы получить свалку потока, просто указав пид процесса:

2.5. jconsole

jconsole позволяет нам проверить стек след каждого потока. Если мы откроем jconsole и подключиться к запущенной Java-процессу, мы можем перейти к Темы вкладка и найти след стека каждого потока :

2.6. Резюме

Как оказалось, существует множество способов захвата свалки потоков с помощью утилит JDK. Давайте на минутку поразмыслим над каждым из них и наметим их плюсы и минусы:

3. От командной линии

На серверах корпоративных приложений по соображениям безопасности устанавливается только JRE. Таким образом, мы не можем использовать вышеупомянутые утилиты, поскольку они являются частью JDK. Тем не менее, существуют различные командно-линейные альтернативы, которые позволяют нам легко захватывать свалки потоков.

3.1. убить -3 Командование (Linux/Unix)

Самый простой способ захвата свалки потоков в системах, похожих на Unix, — это убить команды, которую мы можем использовать для отправки сигнала в процесс с помощью убить () системный вызов. В этом случае мы отправим его в -3 сигнал.

Используя нашу ту же пид из более ранних примеров, давайте посмотрим, как использовать убить для захвата свалки потоков:

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

Если мы забудем процесс Java со следующей комбинацией флагов настройки, то он также перенаправит дампа потока в данный файл:

Теперь, если мы отправим -3 сигнал, в дополнение к стандартному выходу, дамп будет доступен в В/jvm.log файл.

3.2. Ctrl и перерыв (Windows)

В операционных системах Windows мы можем захватить свалку потоков с помощью CTRL и Перерыв ключевая комбинация . Чтобы сделать дампа потока, перейдите на консоль, используемую для запуска java-приложения, и нажмите на CTRL и Перерыв ключи вместе.

Стоит отметить, что на некоторых клавиатурах Перерыв ключ недоступен. Поэтому в таких случаях свалка потока может быть захвачена с помощью CTRL , SHIFT , и Пауза ключи вместе.

Обе эти команды печатают дампа потока на консоль.

4. Программное использование ThreadMxBean

Последний подход, который мы обсудим в статье, это использование JMX . Мы будем использовать ThreadMxBean для захвата свалки потока . Давайте посмотрим его в коде:

В вышеупомянутой программе мы делаем несколько этапов:

  1. Сначала пустая СтрингБуффер инициализируется для хе- итука информации о стеке каждого потока.
  2. Затем мы используем УправлениеФактория класс, чтобы получить экземпляр ThreadMxBean.УправлениеФактория это заводской класс для получения управляемых бобов для платформы Java. Кроме того, ThreadMxBean является интерфейсом управления для системы потоков JVM.
  3. Установка заблокированМониторы и заблокировансинхронизаторы ценности для истинное указывает на захват собственных синхронизаторов и всех заблокированных мониторов в дампах потоков.

5. Заключение

В этой статье мы показали несколько способов захвата свалки потоков.

Сначала мы обсуждали различные утилиты JDK, а затем альтернативы командной линии. В последнем разделе мы завершили с программным подходом с использованием JMX.

-Он может использоваться на любой платформе операционной системы.

-В большинстве случаев его можно использовать в производственной среде.

-По сравнению с инструментами, предоставляемыми операционной системой, информация, предоставляемая дампом потока Java, проста и напрямую соответствует коду приложения.

-Он мало влияет на анализируемую систему, поэтому может отражать реальные проблемы. Многие другие инструменты профилирования или инструменты сами по себе сильно мешают работе JVM, часто не выявляют реальных проблем, и этот инструмент нельзя использовать в производственной системе.

Поток Java

Поток - это исполнительная единица, которая может работать независимо от других частей программы. На языке JAVA вполне можно реализовать многопоточные программы. Когда мы отлаживаем программу или когда нам нужно выполнить настройку производительности на более позднем этапе разработки, нам часто необходимо понимать состояние потока, в котором выполняется текущая программа, и выполняемые операции, чтобы проанализировать возможные проблемы. в системе.

Создать дамп потока JAVA

DUMP потока JAVA, как снимок текущего процесса JAVA, распечатывает состояние и стек вызовов всех потоков, а также состояние монитора. В разных операционных системах способ создания потока DUMP различается.

windows

Hit: Ctrl-Break в консоли программы запуска, и дамп потока будет сгенерирован в стандартном выводе (стандартный вывод по умолчанию - это консоль, если вывод перенаправлен, вам нужно просмотреть выходной файл).

Linux(Unix\MacOS)

Используйте «kill -3 <pid>» или «kill-QUIT <pid>». Pid - это номер интересующего процесса JAVA, вы можете использовать "ps -ef | grep java", чтобы найти его, или команду "jps -v" в JDK 5.0 (или выше), чтобы получить его.

На каждой платформе операционной системы вы можете использовать jstack <pid> в наборе инструментов JDK 5.0 (или выше).

Здесь следует отметить следующее:

1. Метод создания Thread DUMP и формат файла для разных виртуальных машин JAVA различаются, разные версии JVM имеют разную информацию о дампе.

2. В реальной эксплуатации информации дампа часто недостаточно для подтверждения проблемы. Рекомендуется сгенерировать два или три дампа.Если каждый дамп указывает на одну и ту же проблему, мы можем определить типичность проблемы.

Анализ состояния потока

Статус потока - важный индикатор, он будет отображаться в конце первой строки потока Stacktrace. Итак, каковы общие состояния потоков? При каких обстоятельствах поток перейдет в это состояние? Какие ключи мы можем найти?

В файле дампа следует обратить внимание на следующие состояния потоков:
  1. Тупик, Тупик (внимание)
  2. В исполнении Runnable
  3. Жду ресурсов, Ожидание по условию (акцент на)
  4. Жду монитора, Ожидание входа монитора (фокус на)
  5. Приостановлено
  6. Ожидание объекта, Object.wait () или TIMED_WAITING
  7. блок Заблокировано (внимание)
  8. Стоп, на стоянке
Deadlock

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

Runnable

Это состояние указывает на то, что поток имеет все условия выполнения, готов к планированию операционной системы в очереди выполнения или работает.

Waiting on condition

Ожидание ресурсов или наступление определенного условия. Конкретные причины необходимо анализировать вместе со stacktrace.

  • Если информация стека явно является кодом приложения, это доказывает, что поток ожидает ресурсов. Обычно, когда читается большое количество ресурсов и для ресурса используется блокировка ресурса, поток переходит в состояние ожидания и ждет, пока ресурс будет прочитан.
  • Или ожидает выполнения других потоков и т. Д.
  • Если вы обнаружите, что большое количество потоков находится в состоянии ожидания, из стека потоков, они ожидают операций чтения и записи по сети. Это может быть признаком узкого места в сети. Поток не может быть выполнен из-за перегрузки сети.
    • Одна ситуация состоит в том, что сеть очень загружена, почти вся полоса пропускания занята, и все еще есть много данных, ожидающих чтения и записи сетью;
    • Другая ситуация также может заключаться в том, что сеть простаивает, но из-за проблем с маршрутизацией пакеты не могут поступать нормально.
    Blocked

    Блокировка потока означает, что требуемые ресурсы ждали долгое время, но не были получены во время выполнения текущего потока. Диспетчер потоков контейнера идентифицируется как заблокированное состояние, которое можно понимать как поток, ожидающий ресурса тайм-аут.

    Ожидание записи монитора и в Object.wait ()

    Монитор - это основной метод, используемый для достижения взаимного исключения и взаимодействия между потоками в Java. Его можно рассматривать как блокировку объекта или класса. У каждого объекта есть только один монитор. Как видно из рисунка 1 ниже, каждый монитор может принадлежать только одному потоку в определенное время. Этот поток является «активным потоком», а другие потоки - «ожидающим потоком», которые находятся в двух очередях. Установите "" и "Подождите". Состояние потока, ожидающего в «Наборе записей», - «Ожидание записи монитора», а состояние потока, ожидающего в «Наборе ожидания « равно »в Object.wait ( ) ".



    Сначала посмотрите на потоки в «Entry Set». Мы называем сегмент кода, защищенный синхронизированным, критическим разделом. Когда поток обращается к критическому разделу, он попадает в очередь «Entry Set». Соответствующий код выглядит так:

    На данный момент есть две возможности:

    · Монитор не принадлежит другим потокам, и в наборе записей нет других ожидающих потоков. Этот поток становится Владельцем монитора соответствующего класса или объекта и выполняет код критической секции.

    · Монитор принадлежит другим потокам, и этот поток ожидает в очереди набора записей.

    В первом случае поток будет в состоянии «Runnable», а во втором случае поток DUMP будет отображаться как «ожидающий записи монитора». Следующим образом:

    "Thread-0" prio=10 tid=0x08222eb0 nid=0x9 waiting for monitor entry [0xf927b000..0xf927bdb8]

    Настройка критического раздела заключается в обеспечении атомарности и целостности выполнения внутреннего кода. Но поскольку критическая секция позволяет потокам проходить только последовательно в любое время, это противоречит первоначальному замыслу нашей многопоточной программы. Если synchronized часто используется в многопоточной программе или используется ненадлежащим образом, это приведет к тому, что большое количество потоков будет ждать на входе в критический раздел, что приведет к значительному падению производительности системы. Если такая ситуация обнаруживается в потоке DUMP, следует просмотреть исходный код и улучшить программу.

    Теперь давайте посмотрим, почему поток теперь входит в «Набор ожидания». Когда поток получает Monitor и входит в критическую секцию, если он обнаруживает, что условие для продолжения работы потока не выполняется, он вызывает метод wait () объекта (обычно синхронизированного объекта), закрывает Monitor и входит в очередь «Ожидание». Только когда другие потоки вызывают notify () или notifyAll () для объекта, потоки в очереди «Wait Set» получают возможность конкурировать, но только один поток получает Monitor объекта и возвращается в рабочее состояние. Поток в «Wait Set», DUMP отображается как: в Object.wait (), аналогично:

    Если вы внимательно просмотрите информацию о DUMP выше, вы обнаружите, что в ней есть следующие две строки:

    - locked <0xef63beb8> (a java.util.ArrayList)

    - waiting on <0xef63beb8> (a java.util.ArrayList)

    Мне нужно объяснить здесь, почему вы сначала заблокировали этот объект, а затем ждали того же объекта? Давайте посмотрим на код, соответствующий этой теме:

    При выполнении потока Монитор этого объекта (соответствующий заблокированному <0xef63beb8>) сначала получается с помощью synchronized. Когда выполнение достигает obj.wait (), поток отказывается от владения Монитором и входит в очередь «ожидания» (соответствует ожиданию на <0xef63beb8>).

    Часто в вашей программе будет несколько похожих потоков, и все они будут иметь одинаковую информацию DUMP. Это тоже может быть нормально. Например, в программе есть несколько потоков службы, предназначенных для чтения данных запроса из очереди. Эта очередь является объектом блокировки и ожидания. Когда очередь пуста, эти потоки будут ждать в этой очереди, пока в очереди не появятся данные, и эти потоки не будут уведомлены.Конечно, только один поток получает блокировку и продолжает выполнение, в то время как другие потоки продолжают ждать.

    Исчерпывающий пример

    Комплексная демонстрация:Deadlock

    После получения дампа потока java все, что вам нужно сделать, это найти поток «ожидание записи монитора». Если большое количество потоков ожидают блокировки одного и того же адреса (поскольку для Java существует только одна блокировка для объекта ), значит, возможно, возник тупик. такие как:

    "service-j2ee" prio=5 tid=0x024f1c28 nid=0x125 waiting for monitor entry

    [62a3e000..62a3f690]

    [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at

    com.sun.enterprise.resource.IASNonSharedResourcePool.internalGetResource(IASNonS

    haredResourcePool.java:625)

    [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: - waiting to

    lock <0x965d8110> (a com.sun.enterprise.resource.IASNonSharedResourcePool)

    [27/Jun/2006:10:03:08] WARNING (26140): CORE3283: stderr: at

    com.sun.enterprise.resource.IASNonSharedResourcePool.getResource(IASNonSharedRes

    ourcePool.java:520)

    .

    Чтобы определить проблему, часто необходимо снова собрать дамп потока через две минуты.Если результат такой же, значит, все еще существует большое количество потоков, ожидающих блокировки одного и того же адреса, значит, это тупиковая ситуация.

    Как найти поток, удерживающий в данный момент блокировку, - это ключ к решению проблемы. Метод состоит в том, чтобы выполнить поиск в дампе потока, найти «заблокированный <0x965d8110>» и найти поток, удерживающий блокировку.

    В этом примере поток, удерживающий блокировку, ожидает, пока Oracle вернет результат, но никогда не ждет ответа, поэтому возникает взаимоблокировка.

    Если поток, удерживающий блокировку, все еще ожидает блокировки другого объекта, следуйте описанному выше методу, пока не будет найдена основная причина взаимоблокировки.

    Примечание: «service-j2ee» в первой строке - это имя потока. tid относится к идентификатору потока Java. nid относится к идентификатору собственного потока. prio - приоритет потока. [62a3e000..62a3f690] - это начальный адрес стека потоков.

    Читайте также: