Создание дампа потока

Иногда возникают ситуации, при которых 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:

C:\Users\Administrator>jstack.exe -l 22668 > threaddump.txt

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

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

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

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

 

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

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

ps -ef | grep java

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


keithb     910   873  1 17:01 pts/3    00:00:18 /usr/java/jdk/bin/java -Xms128m -Xmx256m
-Xms128m -Xmx256m -Djava.awt.headless=true -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djava.awt.headless=true -Djava.endorsed.dirs=/tmp/atlassian-jira-enterprise-3.6-standalone/common/endorsed
-classpath :

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

kill -3 <pid>

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

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

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

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

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

ps -ef | grep java

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

adam 22668 0.3 14.9 1691788 903928 ? Sl Jan27 9:36 /usr/lib/jvm/java-6-sun-1.6.0.14/bin/java -Djava.util.logging.config.file=/home/adam/Products/installs/atlassian-jira-enterprise-4.0.1-standalone/conf/logging.properties -XX:MaxPermSize=256m -Xms128m -Xmx1048m -Djava.awt.headless=true -Datlassian.standalone=JIRA -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true -Dmail.mime.decodeparameters=true -Datlassian.mail.senddisabled=false -Datlassian.mail.fetchdisabled=false -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/home/adam/Products/installs/atlassian-jira-enterprise-4.0.1-standalone/common/endorsed -classpath /home/adam/Products/installs/atlassian-jira-enterprise-4.0.1-standalone/bin/bootstrap.jar -Dcatalina.base=/home/adam/Products/installs/atlassian-jira-enterprise-4.0.1-standalone -Dcatalina.home=/home/adam/Products/installs/atlassian-jira-enterprise-4.0.1-standalone -Djava.io.tmpdir=/home/adam/Products/installs/atlassian-jira-enterprise-4.0.1-standalone/temp org.apache.catalina.startup.Bootstrap start

 

  1. Запустите jstack <pid> для захвата одиночного дампа потока

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


adam @ jiratrack: ~ $ jstack 22668> JIRAthreaddump.txt

  1. Возьмите несколько дампов потоков

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


adam@jiratrack:~$ jstack 22668 >> JIRAthreaddump.txt
adam@jiratrack:~$ jstack 22668 >> JIRAthreaddump.txt
adam@jiratrack:~$ jstack 22668 >> JIRAthreaddump.txt

 

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

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

ТDA

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

java -jar -Xmx512M ~/tda-bin-1.6/tda.jar

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

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

Если вы получите сообщение об ошибке на консоли TDA, например:


Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "5 os_prio=0"
        at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
        at java.lang.Long.parseLong(Long.java:441)
        at java.lang.Long.(Long.java:702)
        at com.pironet.tda.utils.ThreadsTableModel.getValueAt(ThreadsTableModel.java:80)
        at com.pironet.tda.utils.TableSorter.getValueAt(TableSorter.java:285)
        at javax.swing.JTable.getValueAt(JTable.java:2717)
        at javax.swing.JTable.prepareRenderer(JTable.java:5719)
        at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2114)
        at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:2016)
        at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1812)
        at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
        at javax.swing.JComponent.paintComponent(JComponent.java:778)
        at javax.swing.JComponent.paint(JComponent.java:1054)
        at javax.swing.JComponent.paintChildren(JComponent.java:887)
        at javax.swing.JComponent.paint(JComponent.java:1063)
        at javax.swing.JViewport.paint(JViewport.java:731)
        at javax.swing.JComponent.paintChildren(JComponent.java:887)
        at javax.swing.JComponent.paint(JComponent.java:1063)
        at javax.swing.JComponent.paintChildren(JComponent.java:887)
        at javax.swing.JSplitPane.paintChildren(JSplitPane.java:1047)
        at javax.swing.JComponent.paint(JComponent.java:1063)
        at javax.swing.JComponent.paintToOffscreen(JComponent.java:5230)
        at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:295)
        at javax.swing.RepaintManager.paint(RepaintManager.java:1249)
        at javax.swing.JComponent._paintImmediately(JComponent.java:5178)
        at javax.swing.JComponent.paintImmediately(JComponent.java:4989)
        at javax.swing.RepaintManager$3.run(RepaintManager.java:808)
        at javax.swing.RepaintManager$3.run(RepaintManager.java:796)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:796)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:769)
        at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:718)
        at javax.swing.RepaintManager.access$1100(RepaintManager.java:62)
        at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1677)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:312)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
        at java.awt.EventQueue.access$200(EventQueue.java:103)
        at java.awt.EventQueue$3.run(EventQueue.java:694)
        at java.awt.EventQueue$3.run(EventQueue.java:692)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

Чтобы исправить формат заголовка потока и сделать его обрабатываемым, примените следующую команду в дампах потоков:

sed -i 's / prio = [0-9] \ {1,2 \} os_prio = [0-9] \ {1,2 \} / prio = 5 / g' <имя_файла>

Для Мас:

sed -i '' 's/prio=[0-9]\{1,2\} os_prio=[0-9]\{1,2\}/prio=5/g' <filename>

 

 

По материалам Atlassian JIRA Administrator's Guide: Generating a Thread Dump