- Java get thread dump
- 6. JCMD
- 7. ThreadMXBean
- Share this:
- Получение дампа потока Java
- 2. Использование утилит JDK
- 2.1. jstack
- 2.2. Управление полетами Java
- 2.3. jvisualvm
- 2.4. jcmd
- 2.5. jconsole
- 2.6. Резюме
- 3. Из командной строки
- 3.1. команда kill -3 (Linux/Unix)
- 3.2. Ctrl + Перерыв (Windows)
- 4. Программное использование ThreadMxBean
- 5. Вывод
- How to Generate Java Thread Dump Programmatically
- Want to generate memory Heap Dump on OOM?
Java get thread dump
Java Mission Control (JMC) is a Profiling, Monitoring, and Diagnostics Tools Suite. Java Mission Control is a tool for production time profiling and diagnostics for the HotSpot JVM. The two main features of Java Mission Control are the Management Console and Java Flight Recorder, but several more features are offered as plug-ins, which can be downloaded from the tool.
JMC tool is present in JDK_HOME\bin\jmc, Once you launch the tool, you will see all the Java processes that are running on your local host. JMC uses JVM’s Flight Recorder option to generate thread dumps, which means on your JVM flight recorder option should be enabled with following jvm arguments:
-XX:+UnlockCommercialFeatures -XX:FlightRecorder.
Prior to JDK 8u40 release, the JVM must also have been started with these flags. Since the JDK 8u40 release, the Java Flight Recorder can be enabled during runtime.
As shown in above image, you can choose the different interval time for generating thread dump. Once thread dumps are generated, you can navigate to thread dump pan, to view the generated list of thread dumps.
6. JCMD
The jcmd utility comes with the JDK and is present inside the JAVA_HOME/bin. It is used to send diagnostic command requests to the JVM, where these requests are useful for controlling Java Flight Recordings, troubleshoot, and diagnose JVM and Java Applications. It must be used on the same machine where the JVM is running, and have the same effective user and group identifiers that were used to launch the JVM.
This utility can help us in getting many details about the JVM process. To print all threads with stack traces using Thread.Print
Example: Classes taking the most memory are listed at the top, and classes are listed in a descending order.
jcmd 8845 Thread.print > ~/threadDumps.txt
7. ThreadMXBean
ThreadMXBean is an interface and belongs to java.lang.Management package. It helps to detect the threads which have entered into deadlock condition and also helps in retrieving details about them. ThreadMXBean is an interface, to get an instance of ThreadMXBean use getThreadMXBean() method of ManagementFactory.
Share this:
Получение дампа потока Java
В этом руководстве мы обсудим различные способы захвата дампа потока приложения Java.
Дамп потока — это моментальный снимок состояния всех потоков процесса Java . Состояние каждого потока представлено трассировкой стека, показывающей содержимое стека потока. Дамп потока полезен для диагностики проблем, так как он отображает активность потока. Дампы потоков записываются в виде обычного текста, поэтому мы можем сохранить их содержимое в файл и просмотреть их позже в текстовом редакторе .
В следующих разделах мы рассмотрим несколько инструментов и подходов к созданию дампа потока.
2. Использование утилит JDK
JDK предоставляет несколько утилит, которые могут записывать дамп потока Java-приложения. Все утилиты расположены в папке bin внутри домашнего каталога JDK . Поэтому мы можем запускать эти утилиты из командной строки, пока этот каталог находится в нашем системном пути.
2.1. jstack
jstack — это утилита JDK командной строки, которую мы можем использовать для захвата дампа потока. Он берет pid процесса и отображает дамп потока в консоли. В качестве альтернативы мы можем перенаправить его вывод в файл.
Давайте взглянем на основной синтаксис команды для захвата дампа потока с помощью jstack:
Все флаги необязательны. Давайте посмотрим, что они означают:
- Опция -F принудительно создает дамп потока; удобно использовать, когда jstack pid не отвечает (процесс завис)
- Опция -l указывает утилите искать доступные синхронизаторы в куче и блокировать
- Параметр -m печатает собственные кадры стека (C и C++) в дополнение к кадрам стека Java.
Давайте воспользуемся этим знанием, захватив дамп потока и перенаправив результат в файл:
jstack 17264 > /tmp/threaddump.txt
Помните, что мы можем легко получить pid процесса Java с помощью команды jps .
2.2. Управление полетами Java
Java Mission Control (JMC) — это инструмент с графическим интерфейсом, который собирает и анализирует данные из приложений Java. После запуска JMC отображает список процессов Java, запущенных на локальной машине. Мы также можем подключаться к удаленным процессам Java через JMC.
Мы можем щелкнуть правой кнопкой мыши по процессу и выбрать опцию « Начать запись полета ». После этого на вкладке Threads отображаются дампы потоков:
2.3. jvisualvm
jvisualvm — это инструмент с графическим пользовательским интерфейсом, который позволяет нам отслеживать, устранять неполадки и профилировать приложения Java . Графический интерфейс простой, но очень интуитивно понятный и простой в использовании.
Одна из его многочисленных опций позволяет нам захватить дамп потока. Если мы щелкнем правой кнопкой мыши процесс Java и выберем опцию «Дамп потока» , инструмент создаст дамп потока и откроет его на новой вкладке:
Начиная с JDK 9, Visual VM не входит в дистрибутивы Oracle JDK и Open JDK. Поэтому, если мы используем Java 9 или более новые версии, мы можем получить JVisualVM с сайта проекта Visual VM с открытым исходным кодом .
2.4. jcmd
jcmd — это инструмент, который работает, отправляя командные запросы в JVM. Несмотря на свою мощь, он не содержит удаленных функций; мы должны использовать его на той же машине, где запущен процесс Java.
Одна из его многочисленных команд — Thread.print . Мы можем использовать его для получения дампа потока, просто указав pid процесса:
2.5. jconsole
jconsole позволяет нам проверять трассировку стека каждого потока. Если мы откроем jconsole и подключимся к запущенному процессу Java, мы сможем перейти на вкладку Threads и найти трассировку стека каждого потока :
2.6. Резюме
Как оказалось, есть много способов получить дамп потока с помощью утилит JDK. Давайте поразмыслим над каждым из них и обозначим их плюсы и минусы:
- jstack : обеспечивает самый быстрый и простой способ захвата дампа потока; однако, начиная с Java 8, доступны лучшие альтернативы.
- jmc : улучшенный инструмент профилирования и диагностики JDK. Это сводит к минимуму нагрузку на производительность, которая обычно возникает при использовании инструментов профилирования.
- jvisualvm : легкий инструмент профилирования с открытым исходным кодом и отличной консолью с графическим интерфейсом.
- jcmd : чрезвычайно мощный и рекомендуется для Java 8 и более поздних версий. Единый инструмент, который служит многим целям: захват дампа потока ( jstack ), дампа кучи ( jmap ), системных свойств и аргументов командной строки ( jinfo )
- jconsole : позволяет нам проверять информацию о трассировке стека потока
3. Из командной строки
На корпоративных серверах приложений из соображений безопасности устанавливается только JRE. Таким образом, мы не можем использовать вышеупомянутые утилиты, так как они являются частью JDK. Однако существуют различные альтернативы командной строки, которые позволяют нам легко захватывать дампы потоков.
3.1. команда kill -3 (Linux/Unix)
Самый простой способ захватить дамп потока в Unix-подобных системах — использовать команду kill , которую мы можем использовать для отправки сигнала процессу с помощью системного вызова kill() . В этом случае мы отправим ему сигнал -3 .
Используя тот же pid из предыдущих примеров, давайте посмотрим, как использовать kill для захвата дампа потока:
Таким образом, процесс Java, принимающий сигнал, выведет дамп потока на стандартный вывод.
Если мы запустим процесс Java со следующей комбинацией флагов настройки, то он также перенаправит дамп потока в данный файл:
-XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=~/jvm.log
Теперь, если мы отправим сигнал -3 , помимо стандартного вывода, дамп будет доступен в файле ~/jvm.log .
3.2. Ctrl + Перерыв (Windows)
В операционных системах Windows мы можем захватить дамп потока с помощью комбинации клавиш CTRL и Break . Чтобы получить дамп потока, перейдите к консоли, используемой для запуска приложения Java, и одновременно нажмите клавиши CTRL и Break .
Стоит отметить, что на некоторых клавиатурах клавиша Break недоступна. Поэтому в таких случаях дамп потока можно захватить с помощью клавиш CTRL , SHIFT и Pause вместе.
Обе эти команды выводят дамп потока на консоль.
4. Программное использование ThreadMxBean
Последний подход, который мы обсудим в этой статье, — это использование JMX . Мы будем использовать ThreadMxBean для захвата дампа потока . Давайте посмотрим на это в коде:
private static String threadDump(boolean lockedMonitors, boolean lockedSynchronizers) StringBuffer threadDump = new StringBuffer(System.lineSeparator()); ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); for(ThreadInfo threadInfo : threadMXBean.dumpAllThreads(lockedMonitors, lockedSynchronizers)) threadDump.append(threadInfo.toString()); > return threadDump.toString(); >
В приведенной выше программе мы выполняем несколько шагов:
- Сначала инициализируется пустой StringBuffer для хранения информации о стеке каждого потока.
- Затем мы используем класс ManagementFactory для получения экземпляра ThreadMxBean. ManagementFactory — это фабричный класс для получения управляемых компонентов для платформы Java. Кроме того, ThreadMxBean — это интерфейс управления системой потоков JVM.
- Если задать для LockMonitors и LockSynchronizers значение true , это означает, что синхронизаторы, которыми можно владеть, и все заблокированные мониторы будут захвачены в дамп потока.
5. Вывод
В этой статье мы узнали о нескольких способах захвата дампа потока.
Сначала мы обсудили различные утилиты JDK, а затем альтернативы командной строки. Наконец, мы остановились на программном подходе с использованием JMX.
Как всегда, полный исходный код примера доступен на GitHub .
How to Generate Java Thread Dump Programmatically
The thread dump is a snapshot of exactly what’s executing at a moment in time in your Java Program.
While the thread dump format and content may vary between the different Java vendors, at the bare minimum it provides you a list of the stack traces for all Java threads in the Java Virtual Machine.
Using this information, you can either analyze the problem yourself, or work with those who wrote the running code to analyze the problem.
Thread dump is just a list of all threads and the full stack trace of code running on each thread. If you are a J2EE Application Server administrator and you’ve never done development before, the concept of a stack trace may be foreign to you.
A stack trace is a dump of the current execution stack that shows the method calls running on that thread from the bottom up.
Here is a sample Thread Dump:
"crunchifyThread3" java.lang.Thread.State: RUNNABLE at sun.management.ThreadImpl.getThreadInfo1(Native Method) at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:174) at com.crunchify.tutorials.CrunchifySynchronizeThread.getThreadDump(CrunchifyThreadDeadLock.java:64) at com.crunchify.tutorials.CrunchifySynchronizeThread.run(CrunchifyThreadDeadLock.java:50) at java.lang.Thread.run(Thread.java:722) "crunchifyThread2" java.lang.Thread.State: BLOCKED at com.crunchify.tutorials.CrunchifySynchronizeThread.run(CrunchifyThreadDeadLock.java:53) at java.lang.Thread.run(Thread.java:722) "crunchifyThread1" java.lang.Thread.State: BLOCKED at com.crunchify.tutorials.CrunchifySynchronizeThread.run(CrunchifyThreadDeadLock.java:53) at java.lang.Thread.run(Thread.java:722) "Signal Dispatcher" java.lang.Thread.State: RUNNABLE "Finalizer" java.lang.Thread.State: WAITING at java.lang.Object.wait(Native Method) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:189) "Reference Handler" java.lang.Thread.State: WAITING at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:503) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
Java Method to Generate Thread Dump:
/** * @author Crunchify.com * */ public static String crunchifyGenerateThreadDump() < final StringBuilder dump = new StringBuilder(); final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); final ThreadInfo[] threadInfos = threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds(), 100); for (ThreadInfo threadInfo : threadInfos) < dump.append('"'); dump.append(threadInfo.getThreadName()); dump.append("\" "); final Thread.State state = threadInfo.getThreadState(); dump.append("\n java.lang.Thread.State: "); dump.append(state); final StackTraceElement[] stackTraceElements = threadInfo.getStackTrace(); for (final StackTraceElement stackTraceElement : stackTraceElements) < dump.append("\n at "); dump.append(stackTraceElement); >dump.append("\n\n"); > return dump.toString(); >
In my previous Java Deadlock Example I’ve used the same method to generate thread dump. Here is a list of all Java Examples and Spring MVC Examples which you may be interested in.
Want to generate memory Heap Dump on OOM?
Please use -XX:+HeapDumpOnOutOfMemory parameter while starting java application.
If you liked this article, then please share it on social media. Have a question or suggestion? Please leave a comment to start the discussion.