Введение
В предыдущей статье мы представили использование инструмента jstat в JDK 14. В этой статье мы подробно обсудим использование инструмента jstack.
Инструмент jstack в основном используется для печати информации о стеке Java, в основном имени класса Java, имени метода, индексе байт-кода, номере строки и другой информации.
Для получения более интересного контента см.:
- Серия руководств от входа до отказа от блокчейна, охватывающая криптографию, гиперреестр, Ethereum, Libra, биткойн и другие непрерывные обновления.
- Серия руководств по Spring Boot 2.X: освоение Spring Boot с нуля за семь дней — постоянное обновление
- Серия руководств по Spring 5.X: Удовлетворите все свои представления о непрерывном обновлении Spring5
- Путь Java-программистов от мелких рабочих до экспертов, чтобы стать богами (версия 2020 г.) - постоянно обновляется, с подробными статьями и учебными пособиями.
Для получения дополнительной информации, пожалуйста, посетитеwww.flydean.com
Формат команды jstack
Usage:
jstack [-l][-e] <pid>
(to connect to running process)
Options:
-l long listing. Prints additional information about locks
-e extended listing. Prints additional information about threads
-? -h --help -help to print this help message
Параметры jstack относительно просты, l может содержать информацию о блокировке, а e содержит дополнительную информацию.
Использование jstack
Возьмем пример:
jstack -l -e 53528
Результат выглядит следующим образом:
2020-05-09 21:46:51
Full thread dump Java HotSpot(TM) 64-Bit Server VM (14.0.1+7 mixed mode, sharing):
Threads class SMR info:
_java_thread_list=0x00007fda0660eb00, length=14, elements={
0x00007fda04811000, 0x00007fda05845800, 0x00007fda05012000, 0x00007fda05847800,
0x00007fda05843800, 0x00007fda05854800, 0x00007fda0481f000, 0x00007fda0481f800,
0x00007fda04018800, 0x00007fda041ff800, 0x00007fda05a28800, 0x00007fda05b1a800,
0x00007fda05b1d800, 0x00007fda042be000
}
"Reference Handler" #2 daemon prio=10 os_prio=31 cpu=0.67ms elapsed=66335.21s allocated=0B defined_classes=0 tid=0x00007fda04811000 nid=0x4603 waiting on condition [0x000070000afe1000]
java.lang.Thread.State: RUNNABLE
at java.lang.ref.Reference.waitForReferencePendingList(java.base@14.0.1/Native Method)
at java.lang.ref.Reference.processPendingReferences(java.base@14.0.1/Reference.java:241)
at java.lang.ref.Reference$ReferenceHandler.run(java.base@14.0.1/Reference.java:213)
Locked ownable synchronizers:
- None
...
"VM Thread" os_prio=31 cpu=1433.78ms elapsed=66335.22s tid=0x00007fda0506b000 nid=0x4803 runnable
"GC Thread#0" os_prio=31 cpu=18.63ms elapsed=66335.23s tid=0x00007fda0502a800 nid=0x3203 runnable
"GC Thread#1" os_prio=31 cpu=19.64ms elapsed=66334.06s tid=0x00007fda050e5800 nid=0x9d03 runnable
"GC Thread#2" os_prio=31 cpu=17.72ms elapsed=66334.06s tid=0x00007fda05015000 nid=0x6203 runnable
"GC Thread#3" os_prio=31 cpu=14.57ms elapsed=66332.78s tid=0x00007fda05138800 nid=0x6503 runnable
"G1 Main Marker" os_prio=31 cpu=0.25ms elapsed=66335.23s tid=0x00007fda05031000 nid=0x3303 runnable
"G1 Conc#0" os_prio=31 cpu=14.85ms elapsed=66335.23s tid=0x00007fda05031800 nid=0x4b03 runnable
"G1 Refine#0" os_prio=31 cpu=3.25ms elapsed=66335.23s tid=0x00007fda0583a800 nid=0x4a03 runnable
"G1 Young RemSet Sampling" os_prio=31 cpu=5929.79ms elapsed=66335.23s tid=0x00007fda0505a800 nid=0x3503 runnable
"VM Periodic Task Thread" os_prio=31 cpu=21862.12ms elapsed=66335.13s tid=0x00007fda0505b000 nid=0xa103 waiting on condition
JNI global refs: 43, weak refs: 45
Результаты вывода можно разделить на следующие части:
Информация о виртуальной машине JVM
Первая часть — это информация о виртуальной машине JVM.
2020-05-09 21:46:51
Full thread dump Java HotSpot(TM) 64-Bit Server VM (14.0.1+7 mixed mode, sharing):
Выше показана такая информация, как время дампа потока виртуальной машины и версия виртуальной машины.
Threads class SMR info
Вторая часть — это информация о внутреннем потоке не-JVM (не-VM и не-GC-потоки) в JVM.
Threads class SMR info:
_java_thread_list=0x00007fda0660eb00, length=14, elements={
0x00007fda04811000, 0x00007fda05845800, 0x00007fda05012000, 0x00007fda05847800,
0x00007fda05843800, 0x00007fda05854800, 0x00007fda0481f000, 0x00007fda0481f800,
0x00007fda04018800, 0x00007fda041ff800, 0x00007fda05a28800, 0x00007fda05b1a800,
0x00007fda05b1d800, 0x00007fda042be000
}
Эти элементы сопоставляются с tid следующего потока. Представляет адрес объекта локального потока, обратите внимание, что это не идентификаторы потоков.
Вы могли заметить, что там написано SMR, а полное название SMR — Safe Memory Reclamation.
Что такое СМР? Проще говоря, это безопасное выделение памяти, Обычно эта проблема возникает в неавтоматических языках программирования GC, таких как C++. В этих языках вам необходимо выделять память для объектов и уничтожать объекты самостоятельно, что может привести к тому, что в многопоточной среде адрес может быть назначен нескольким объектам, что приведет к небезопасному выделению памяти.
информация о потоке
Третья часть — это конкретная информация о потоке:
"Reference Handler" #2 daemon prio=10 os_prio=31 cpu=0.67ms elapsed=66335.21s allocated=0B defined_classes=0 tid=0x00007fda04811000 nid=0x4603 waiting on condition [0x000070000afe1000]
java.lang.Thread.State: RUNNABLE
at java.lang.ref.Reference.waitForReferencePendingList(java.base@14.0.1/Native Method)
at java.lang.ref.Reference.processPendingReferences(java.base@14.0.1/Reference.java:241)
at java.lang.ref.Reference$ReferenceHandler.run(java.base@14.0.1/Reference.java:213)
Locked ownable synchronizers:
- None
В соответствии с порядком полей мы можем разделить информацию о потоке на следующие части:
- Имя потока: например, обработчик ссылок
- Идентификатор темы: например, № 2
- Поток демона: например, потоки демона, демона являются потоками с низким приоритетом, и их роль заключается в предоставлении услуг для пользовательского потока. Из-за низкого приоритета потоков демона и предоставления услуг только для пользовательских потоков JVM автоматически завершит работу, когда все пользовательские потоки будут завершены, независимо от того, есть ли еще запущенные потоки демона.
- Приоритет: например, prio=10
- Приоритет потока ОС: например, os_prio=31
- cpu time: время, за которое поток получает процессор, например, cpu=0,67 мс.
- истекло: время настенных часов истекло после запуска потока
- выделено: количество выделенных байтов, выделенных этим потоком
- defined_classes: количество классов, определенных этим потоком
Обратите внимание, что 'allocated=' и 'defined_classes=' должны быть включены с -XX:+PrintExtendedThreadInfo для вывода данных.
- Адрес: адрес потока Java, например: tid=0x00007fda04811000
- Идентификатор потока ОС: например, nid=0x4603
- Статус потока: например, ожидание по условию
- последний указатель стека Java: последний указатель стека Java SP, например: [0x000070000afe1000]
Thread Stack Trace
Далее идет информация о стеке потока:
java.lang.Thread.State: RUNNABLE
at java.lang.ref.Reference.waitForReferencePendingList(java.base@14.0.1/Native Method)
at java.lang.ref.Reference.processPendingReferences(java.base@14.0.1/Reference.java:241)
at java.lang.ref.Reference$ReferenceHandler.run(java.base@14.0.1/Reference.java:213)
В приведенном выше примере представлена информация о стеке потока и указано его состояние.
Locked Ownable Synchronizer
Следующая часть — объект монопольной блокировки, принадлежащий потоку и доступный для синхронизации.
Ownable Synchronizer — это синхронизатор, свойства синхронизации которого реализуются с помощью AbstractOwnableSynchronizer или его подклассов.
Например, блокировка записи в ReentrantLock и ReentrantReadWriteLock (обратите внимание, не блокировка чтения, поскольку требуется эксклюзивность) являются двумя примерами.
JVM Threads
Далее идет информация о потоке JVM, поскольку этот поток является внутренним для JVM, поэтому идентификатор потока отсутствует:
"VM Thread" os_prio=31 cpu=1433.78ms elapsed=66335.22s tid=0x00007fda0506b000 nid=0x4803 runnable
"GC Thread#0" os_prio=31 cpu=18.63ms elapsed=66335.23s tid=0x00007fda0502a800 nid=0x3203 runnable
"GC Thread#1" os_prio=31 cpu=19.64ms elapsed=66334.06s tid=0x00007fda050e5800 nid=0x9d03 runnable
"GC Thread#2" os_prio=31 cpu=17.72ms elapsed=66334.06s tid=0x00007fda05015000 nid=0x6203 runnable
"GC Thread#3" os_prio=31 cpu=14.57ms elapsed=66332.78s tid=0x00007fda05138800 nid=0x6503 runnable
"G1 Main Marker" os_prio=31 cpu=0.25ms elapsed=66335.23s tid=0x00007fda05031000 nid=0x3303 runnable
"G1 Conc#0" os_prio=31 cpu=14.85ms elapsed=66335.23s tid=0x00007fda05031800 nid=0x4b03 runnable
"G1 Refine#0" os_prio=31 cpu=3.25ms elapsed=66335.23s tid=0x00007fda0583a800 nid=0x4a03 runnable
"G1 Young RemSet Sampling" os_prio=31 cpu=5929.79ms elapsed=66335.23s tid=0x00007fda0505a800 nid=0x3503 runnable
"VM Periodic Task Thread" os_prio=31 cpu=21862.12ms elapsed=66335.13s tid=0x00007fda0505b000 nid=0xa103 waiting on condition
JNI References
Последняя часть — это информация о ссылках JNI (Java Native Interface).Обратите внимание, что эти ссылки могут вызвать утечку памяти, поскольку эти собственные ссылки не будут автоматически удалены сборщиком мусора.
JNI global refs: 43, weak refs: 45
Суммировать
jstack — очень мощный инструмент для анализа потоков, надеюсь, вы сможете его использовать.
Автор статьи: о программе flydean
Ссылка на эту статью:Woohoo. Флойд press.com/JDK14-JVM-просто…
Источник этой статьи: блог flydean
Добро пожаловать, обратите внимание на мой публичный номер: вас ждут самые интересные вещи о программе!