Статьи

Как проанализировать дамп потока — трассировка стека потока

Эта статья является частью 5 нашей серии анализов Thread Dump . До сих пор вы изучали основные принципы потоков и их взаимодействия с вашим контейнером Java EE и JVM. Вы также изучили различные форматы Thread Dump для HotSpot и IBM Java VM. Настало время для вас глубоко погрузиться в процесс анализа.

Для того, чтобы вы могли быстро определить шаблон проблемы из дампа потока, вам сначала нужно понять, как прочитать трассировку стека потоков и как правильно «рассказать» историю. Это означает, что если я попрошу вас рассказать мне, что делает Thread # 38; вы должны быть в состоянии точно ответить; в том числе, если трассировка стека потоков показывает исправное (нормальное) состояние против зависания.

Пересмотр стека Java

Большинство из вас знакомы с трассировкой стека Java. Это типичные данные, которые мы находим из файлов журналов сервера и приложения, когда выдается исключение Java. В этом контексте трассировка стека Java дает нам путь выполнения кода потока, который вызвал исключение Java, такой как java.lang.NoClassDefFoundError, java.lang.NullPpointerException и т. Д. Такой путь выполнения кода позволяет нам видеть различные уровни кода, который в конечном итоге приводит к исключению Java.

Трассировки стека Java всегда должны читаться снизу вверх:

  • Строка внизу будет отображать отправителя запроса, такого как поток контейнера Java / Java EE.
  • Первая строка в верхней части трассировки стека покажет вам класс Java, где сработало последнее исключение.

Давайте пройдем через этот процесс на простом примере. Мы создали образец Java-программы, просто выполняя некоторые вызовы методов класса и выбрасывая исключение. Сгенерированный вывод программы приведен ниже:

1
2
3
4
5
6
7
8
JavaStrackTraceSimulator
Author: Pierre-Hugues Charbonneau
http://javaeesupportpatterns.blogspot.com
 
Exception in thread "main" java.lang.IllegalArgumentException:
        at org.ph.javaee.training.td.Class2.call(Class2.java:12)
        at org.ph.javaee.training.td.Class1.call(Class1.java:14)
        at org.ph.javaee.training.td.JavaSTSimulator.main(JavaSTSimulator.java:20)
  • Java-программа JavaSTSimulator вызывается (через «основной» поток)
  • Затем симулятор вызывает вызов метода () из Class1
  • Вызов метода Class1 () затем вызывает вызов метода Class2 ()
  • Вызов метода Class2 () вызывает исключение Java: java.lang.IllegalArgumentException
  • Java Exception затем отображается в журнале / стандартный вывод

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

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

Thread Dump: анализ трассировки стека потоков

Дамп потока, сгенерированный из JVM, предоставляет вам моментальный снимок выполнения на уровне кода всех «созданных» потоков всего процесса JVM. Созданные потоки не означают, что все эти потоки действительно что-то делают. В типичном снимке потока дампа, созданном из JVM контейнера Java EE:

  • Некоторые потоки могут выполнять необработанные вычислительные задачи, такие как синтаксический анализ XML, доступ к IO / диску и т. Д.
  • Некоторые потоки могут ожидать блокирующие вызовы ввода-вывода, такие как удаленный вызов веб-службы, запрос DB / JDBC и т. Д.
  • Некоторые потоки могут быть вовлечены в сборку мусора в то время, например, потоки GC
  • Некоторые потоки будут ожидать выполнения некоторой работы (потоки, не выполняющие никакой работы, обычно переходят в состояние ожидания ())
  • Некоторые потоки могут ожидать завершения работы других потоков, например, потоки, ожидающие получения блокировки монитора (синхронизированный блок {}) для некоторых объектов

Я вернусь к вышесказанному с большим количеством диаграмм в моей следующей статье, но сейчас давайте сосредоточимся на процессе анализа трассировки стека. Ваша следующая задача — прочитать трассировку стека потоков и понять, что она делает, насколько вам известно.

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

  • Начните читать трассировку стека потоков снизу
  • Во-первых, определите отправителя (поток контейнера Java EE, пользовательский поток, поток GC, внутренний поток JVM, отдельная «основная» тема Java-программы и т. Д.)
  • Следующим шагом является определение типа запроса, который выполняет Поток (WebApp, Web-сервис, JMS, Удаленный EJB (RMI), внутренний контейнер Java EE и т. Д.)
  • Следующим шагом является определение формы трассировки стека выполнения вашего модуля (ей) приложения, например, фактической основной работы, которую Поток пытается выполнить. Сложность анализа будет зависеть от уровней абстракции среды промежуточного программного обеспечения и приложения.
  • Следующим шагом является просмотр последних ~ 10-20 строк перед первой строкой. Определите протокол или работу, в которой участвует Поток, например, вызов HTTP, обмен данными через сокет, JDBC или необработанные вычислительные задачи, такие как доступ к диску, загрузка классов и т. Д.
  • Следующий шаг — посмотреть на первую строку. В первой строке обычно указывается LOT в состоянии Thread, поскольку это текущий фрагмент кода, выполненный во время создания снимка
  • Комбинация двух последних шагов — это то, что даст вам основную информацию, чтобы сделать вывод о том, с какой работой и / или зависанием связан поток.

Ниже приведена визуальная разбивка вышеперечисленных шагов с использованием реального примера трассировки стека потоков дампа потока, полученной из производственной среды JBoss 5. В этом примере многие потоки демонстрировали схожий шаблон проблемы избыточного ввода-вывода при создании новых экземпляров экземпляров службы JAX-WS.
thread_stack_trace_sample

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

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

Ссылка: Как проанализировать дамп потока. Часть 5. Трассировка стека потоков от нашего партнера по JCG Пьера-Хьюга Шарбонно из блога по шаблонам поддержки Java EE и учебному пособию по Java .