Статьи

JVM: Как проанализировать дамп потока

В этой статье вы узнаете, как анализировать дамп потока JVM и точно определять причину вашей проблемы. С моей точки зрения, анализ дампа потоков является наиболее важным набором навыков для любого человека, вовлеченного в поддержку производства Java EE. Объем информации, которую вы можете получить из моментальных снимков Thread Dump, часто намного превосходит то, что вы можете себе представить.

Моя цель — поделиться с вами своими знаниями по анализу потоковых дампов, которые я накопил за последние 10 лет, например, сотни циклов анализа потоковых дампов с десятками общих моделей проблем во многих версиях JVM и поставщиках JVM.

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

Звучит хорошо, мне действительно нужно улучшить свои навыки работы с Thread Dump … так с чего же начать?

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

1) Обзор дампа нити и основы
2) Методы генерации дампов и доступные инструменты
3) Различия в форматах дампов потоков между Sun HotSpot, IBM JRE и Oracle JRockit
4) объяснение и интерпретация трассировки стека потоков
5) Анализ дампа потока и методы корреляции
6) Шаблоны типичных проблем потока дампа (гонка потока, тупик, зависание вызовов ввода-вывода, сборка мусора / проблемы OutOfMemoryError, бесконечный цикл и т. Д.)
7) Примеры дампов в реальных примерах

Я действительно надеюсь, что этот учебный план по анализу дампов будет полезен для вас, поэтому, пожалуйста, следите за еженедельными обновлениями и статьями!

Но что, если у меня все еще есть вопросы или я все еще пытаюсь понять эти учебные статьи?

Не волнуйся, и, пожалуйста, считай меня своим тренером. Я настоятельно рекомендую вам задать мне любой вопрос о дампе темы ( помните, что глупых вопросов нет ), поэтому я предлагаю вам следующие варианты бесплатно; Просто выберите модель общения, которая вам удобнее:

1) Отправьте свой вопрос, связанный с дампом темы, разместив свой комментарий под статьей ( пожалуйста, не стесняйтесь оставаться анонимным )
2) Отправьте свои данные дампа темы на форум анализа первопричин
3) Пришлите мне по электронной почте свои вопросы, связанные с дампом темы @ [email protected]

Могу ли я отправить вам свои данные Thread Dump из моей производственной среды / серверов?

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

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

Прежде чем углубляться в анализ дампов потоков и шаблоны проблем, очень важно, чтобы вы поняли основы. Эта статья будет охватывать основы и позволит вам улучшить взаимодействие JVM и промежуточного ПО с вашим контейнером Java EE.

Обзор виртуальной машины Java

Виртуальная машина Java действительно является основой любой платформы Java EE. Здесь ваше промежуточное ПО и приложения развернуты и активны.

JVM предоставляет промежуточному программному обеспечению и вашей программе Java / Java EE:

— Среда выполнения для вашей программы Java / Java EE (формат байт-кода)
— Несколько программных функций и утилит (средства ввода-вывода, структура данных, управление потоками, безопасность, мониторинг и т. Д.)
— Динамическое выделение памяти и управление через сборщик мусора

Ваша JVM может находиться во многих ОС (Solaris, AIX, Windows и т. Д.), И в зависимости от спецификаций вашего физического сервера вы можете установить 1… n процессов JVM на физический / виртуальный сервер.

Взаимодействие программного обеспечения JVM и Middleware

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

Здесь показана типичная и простая схема взаимодействия между JVM, промежуточным программным обеспечением и приложением. Как вы можете видеть, распределение потоков для стандартного приложения Java EE осуществляется в основном между самим ядром промежуточного программного обеспечения и JVM ( есть некоторые исключения, когда само приложение или некоторые API-интерфейсы создают потоки напрямую, но это не является распространенным явлением и должно выполняться очень осторожно ). ,

Также обратите внимание, что некоторые потоки управляются внутри самой JVM, например, потоки GC (сборка мусора), для обработки одновременных сборок мусора.

Поскольку большинство выделений потоков выполняется контейнером Java EE, важно, чтобы вы понимали и распознавали трассировку стека потоков и правильно идентифицировали ее по данным дампа потоков. Это позволит вам быстро понять тип запроса, который пытается выполнить контейнер Java EE.

С точки зрения анализа дампа потока вы узнаете, как различать различные пулы потоков, найденные в JVM, и определять тип запроса.

Этот последний раздел предоставит вам обзор того, что представляет собой дамп потока JVM для виртуальной машины HotSpot и различных потоков, которые вы найдете. Подробная информация о формате IBM VM Thread Dump будет представлена ​​в части 4.

Обратите внимание, что вы найдете образец Thread Dump, использованный для этой статьи, на форуме анализа первопричин .

JVM Thread Dump — что это?

Дамп потока JVM — это снимок, сделанный в определенный момент времени, который предоставляет вам полный список всех созданных потоков Java.

Каждый найденный отдельный поток Java предоставляет вам такую ​​информацию, как:

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

Тип и приоритет потока, например: daemon prio = 3 ** ПО промежуточного программного обеспечения обычно создает свои потоки как демон, что означает, что их потоки работают в фоновом режиме; предоставление услуг своему пользователю, например, вашему приложению Java EE **

Идентификатор потока Java ex: tid = 0x000000011e52a800 ** Это идентификатор потока Java, полученный с помощью java.lang.Thread.getId () и обычно реализуемый как автоматически увеличивающийся long 1..n **

Собственный идентификатор потока, например: nid = 0x251c ** Важная информация, так как этот собственный идентификатор потока позволяет сопоставить, например, какие потоки с точки зрения ОС используют больше всего ЦП в вашей JVM и т. Д. **

Состояние потока Java и детали, например: ожидание записи монитора [0xfffffffea5afb000] java.lang.Thread.State: BLOCKED (на объектном мониторе)
** Позволяет быстро узнать о состоянии потока и его потенциальном текущем состоянии блокировки **

трассировка стека Java Thread ; это, безусловно, самые важные данные, которые вы найдете в дампе потока. Это также то место, где вы будете проводить большую часть времени на анализ, поскольку Java Stack Trace предоставляет вам 90% информации, которая вам необходима для точного определения основной причины многих типов проблемных шаблонов, о чем вы узнаете позже на учебных занятиях.

разбивка кучи Java ; начиная с HotSpot VM 1.6, вы также найдете в нижней части снимка потока дамп разбивку использования пространств памяти HotSpot, таких как пространство Java Heap (YoungGen, OldGen) и PermGen. Это очень полезно, когда в качестве возможной основной причины подозревается избыточный GC, поэтому вы можете выполнить готовую корреляцию с найденными данными / образцами потоков.

1
2
3
4
5
6
7
8
9
Heap
PSYoungGen      total 466944K, used 178734K [0xffffffff45c00000, 0xffffffff70800000, 0xffffffff70800000)
eden space 233472K, 76% used [0xffffffff45c00000,0xffffffff50ab7c50,0xffffffff54000000)
from space 233472K, 0% used [0xffffffff62400000,0xffffffff62400000,0xffffffff70800000)
to   space 233472K, 0% used [0xffffffff54000000,0xffffffff54000000,0xffffffff62400000)
PSOldGen        total 1400832K, used 1400831K [0xfffffffef0400000, 0xffffffff45c00000, 0xffffffff45c00000)
object space 1400832K, 99% used [0xfffffffef0400000,0xffffffff45bfffb8,0xffffffff45c00000)
PSPermGen       total 262144K, used 248475K [0xfffffffed0400000, 0xfffffffee0400000, 0xfffffffef0400000)
object space 262144K, 94% used [0xfffffffed0400000,0xfffffffedf6a6f08,0xfffffffee0400000)

Обзор разбивки дампов нитей

Чтобы лучше понять, ниже приведена диаграмма, показывающая визуальную разбивку найденного дампа потоков HotSpot VM и его общих пулов потоков:

Как вы можете, есть несколько фрагментов информации, которые вы можете найти в дампе HotSpot VM Thread Dump. Некоторые из этих частей будут более важными, чем другие, в зависимости от вашей модели проблемы (модели проблемы будут смоделированы и объяснены в будущих статьях).

А пока найдите ниже подробное объяснение каждого раздела дампа темы в соответствии с нашим примером дампа темы HotSpot:

# Полный идентификатор дампа потока
По сути, это уникальное ключевое слово, которое вы найдете в стандартном журнале вывода промежуточного программного обеспечения / стандартного Java после создания дампа потока (например, через kill -3 <PID> для UNIX). Это начало данных снимка потока дампа.

1
Full thread dump Java HotSpot(TM) 64-Bit Server VM (20.0-b11 mixed mode):

# Промежуточное ПО Java EE, сторонние и пользовательские потоки приложений
Эта часть является ядром Thread Dump и где вы обычно проводите большую часть времени на анализ. Количество найденных потоков будет зависеть от используемого вами программного обеспечения промежуточного программного обеспечения, сторонних библиотек (которые могут иметь свои собственные потоки) и вашего приложения ( если создается какой-либо пользовательский поток, что, как правило, не рекомендуется ).

В нашем образце Thread Dump используется Weblogic. Начиная с Weblogic 9.2, используется самонастраивающийся пул потоков с уникальным идентификатором «weblogic.kernel.Default (самонастройка)».

1
2
3
4
5
6
7
8
"[STANDBY] ExecuteThread: '414' for queue: 'weblogic.kernel.Default (self-tuning)'" daemon prio=3 tid=0x000000010916a800 nid=0x2613 in Object.wait() [0xfffffffe9edff000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0xffffffff27d44de0> (a weblogic.work.ExecuteThread)
        at java.lang.Object.wait(Object.java:485)
        at weblogic.work.ExecuteThread.waitForRequest(ExecuteThread.java:160)
        - locked <0xffffffff27d44de0> (a weblogic.work.ExecuteThread)
        at weblogic.work.ExecuteThread.run(ExecuteThread.java:181)

# HotSpot VM Thread
Это внутренний поток, управляемый виртуальной машиной HotSpot для выполнения внутренних собственных операций. Как правило, вам не следует беспокоиться об этом, если вы не видите высокую загрузку ЦП (из-за дампов потока и prstat / родной корреляции идентификаторов потоков).

1
"VM Periodic Task Thread" prio=3 tid=0x0000000101238800 nid=0x19 waiting on condition

# HotSpot GC Thread
При использовании параллельного GC HotSpot (довольно распространенного в наши дни при использовании оборудования с несколькими физическими ядрами) виртуальная машина HotSpot создает по умолчанию или в соответствии с настройкой JVM определенное количество потоков GC. Эти потоки GC позволяют виртуальной машине выполнять периодические очистки GC параллельно, что приводит к общему сокращению времени GC; за счет увеличения загрузки процессора.

1
2
3
"GC task thread#0 (ParallelGC)" prio=3 tid=0x0000000100120000 nid=0x3 runnable
"GC task thread#1 (ParallelGC)" prio=3 tid=0x0000000100131000 nid=0x4 runnable
………………………………………………………………………………………………………………………………………………………………

Это также важные данные, поскольку, сталкиваясь с проблемами, связанными с сборкой мусора, такими как чрезмерная сборка мусора, утечки памяти и т. Д., Вы сможете сопоставить любой высокий процессор, наблюдаемый в процессе (ах) ОС / Java, с этими потоками, используя их собственное значение идентификатора (nid = 0х3). Вы узнаете, как определить и подтвердить эту проблему в следующих статьях.

Количество глобальных ссылок JNI
Глобальные ссылки JNI (Java Native Interface) — это, в основном, ссылки на объекты из собственного кода на объект Java, управляемый сборщиком мусора Java. Его роль заключается в предотвращении сбора объекта, который все еще используется собственным кодом, но технически не имеет «живых» ссылок в коде Java.

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

1
JNI global references: 1925

# Вид использования кучи Java
Эти данные были добавлены обратно в JDK 1 .6 и предоставляют вам краткое и быстрое представление вашей кучи HotSpot. Я нахожу это весьма полезным при устранении неполадок, связанных с GC, а также с процессором HIGH, поскольку вы получаете дамп потока и кучу Java в одном снимке, позволяя определить (или исключить) любую точку давления в определенном пространстве памяти Java Heap вместе с текущей В это время выполняются потоковые вычисления. Как вы можете видеть в нашем примере Thread Dump, Java Heap OldGen исчерпан!

1
2
3
4
5
6
7
8
9
Heap
 PSYoungGen      total 466944K, used 178734K [0xffffffff45c00000, 0xffffffff70800000, 0xffffffff70800000)
  eden space 233472K, 76% used [0xffffffff45c00000,0xffffffff50ab7c50,0xffffffff54000000)
  from space 233472K, 0% used [0xffffffff62400000,0xffffffff62400000,0xffffffff70800000)
  to   space 233472K, 0% used [0xffffffff54000000,0xffffffff54000000,0xffffffff62400000)
 PSOldGen        total 1400832K, used 1400831K [0xfffffffef0400000, 0xffffffff45c00000, 0xffffffff45c00000)
  object space 1400832K, 99% used [0xfffffffef0400000,0xffffffff45bfffb8,0xffffffff45c00000)
 PSPermGen       total 262144K, used 248475K [0xfffffffed0400000, 0xfffffffee0400000, 0xfffffffef0400000)
  object space 262144K, 94% used [0xfffffffed0400000,0xfffffffedf6a6f08,0xfffffffee0400000)

Я надеюсь, что эта статья помогла понять базовый взгляд на дамп потока в виртуальной машине HotSpot. Следующая статья предоставит вам тот же обзор и описание дампа потока для виртуальной машины IBM.

Пожалуйста, не стесняйтесь оставлять комментарии или вопросы.

Справка: Как анализировать поток дампов — часть 1 ,   Как проанализировать дамп потока — часть 2: обзор JVM и как проанализировать дамп потока — часть 3: виртуальная машина HotSpot от нашего партнера по JCG   Pierre-Hugues Charbonneau из блога поддержки шаблонов Java EE и учебного курса по Java .