Выявление неисправностей приложений

Материал из BiTel WiKi

Перейти к: навигация, поиск

Удаленная отладка

Необходимо запустить приложение со следующими ключами:

-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=5589,server=y,suspend=n

После этого можно создать в Eclipse конфигурацию запуска Remote Java Application, поставить точку останова и отлаживать удаленный процесс как локальный. Естесственно, что нужно организовать доступ к порту на машине с процессом (5589) с машины с запущенной IDE.

Метод подходит для выявления воспроизводимых ошибок непосредственно на работающем приложении.

Снятие стека

Выполняется утилитой jstack, входящей в комплект JDK. Она снимает стэк конкртного java-процесса. Например у нас есть такие процессы в системе:

bg-bill1:/usr/local/BGBillingServer # ps axwww | grep java
 2701 ?        Sl    33:15 /opt/java/jre/bin/java -Dapp.name=BGBillingServer -Dnetworkaddress.cache.ttl=3600 -Xmx1000m -cp .:./lib/* ru.bitel.common.bootstrap.Boot bitel.billing.server.Server start
 2703 ?        Sl     1:11 /usr/java/default/bin/java -Dapp.name=BGIPNNetflowCollector -Dlog4j.configuration=log4j-collector.xml -Dlog.dir.path=log/ -Dnetworkaddress.cache.ttl=3600 -Xmx256m -Djava.awt.headless=true -cp .:./lib/* bitel.billing.server.netflow.ipn.Collector start
 2721 ?        Sl    17:15 /usr/java/default/bin/java -Dapp.name=BGRadiusDialup -Xmx256m -Dlog4j.configuration=log4j-radius.xml -Dlog.dir.path=log/ -cp .:./lib/* bitel.billing.server.radius.Radius start
 2753 ?        Sl    21:15 /opt/java/jre/bin/java -Dapp.name=BGScheduler -Xmx1000m -cp .:./lib/* ru.bitel.common.bootstrap.Boot bitel.billing.server.TaskExecuter -estart
 3656 ?        Sl     0:04 /opt/java/jre/bin/java -Dapp.name=BGDataLoader -Dnetworkaddress.cache.ttl=3600 -Xmx1000m -cp .:./lib/* ru.bitel.common.bootstrap.Boot bitel.billing.server.DataLoader -estart
 8822 pts/1    R+     0:00 grep java

Мы решили снять стэк с процесса сервера BGBilling (код 2701) :

bg-bill1:/usr/local/BGBillingServer # /opt/java/jdk/bin/jstack 2701 | more
2009-06-23 14:46:04
Full thread dump Java HotSpot(TM) Server VM (11.2-b01 mixed mode):
 
"Attach Listener" daemon prio=10 tid=0x08310000 nid=0x2285 waiting on condition [0x00000000..0x00000000]
   java.lang.Thread.State: RUNNABLE
 
"http-8080-8" daemon prio=10 tid=0x08c89c00 nid=0x1fb2 in Object.wait() [0x6fd7e000..0x6fd7f150]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x7720d2e8> (a org.apache.tomcat.util.net.JIoEndpoint$Worker)
        at java.lang.Object.wait(Object.java:485)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:416)
        - locked <0x7720d2e8> (a org.apache.tomcat.util.net.JIoEndpoint$Worker)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:442)
        at java.lang.Thread.run(Unknown Source)
 
"http-8080-7" daemon prio=10 tid=0x08536000 nid=0x1eaf in Object.wait() [0x7005c000..0x7005d150]
   java.lang.Thread.State: WAITING (on object monitor)
.....

Метод хорошо подходит для определения причины "зависания" плиложений по причине взаимоблокировок процессов (Dead Lock). Подобные блокировки определяются автоматически с указанием строк исходного кода.

Снятие дампа памяти

jmap -dump:format=b,file=snapshot.jmap PID_OF_PROCESS

Просмотр дампа:

jhat -J-mx512m snapshot.jmap

Утилиты jmap, jhat входят в Sun JDK. Следует учитывать, что для просмотра дампа размером Х приложению jhat потребуется выделить объем памяти примерно X*3 - X*4. В приведенном примере выделено 512 МБ. Полученный результат можно можно смотреть через web-интерфейс. Для этого надо зайти на http://localhost:7000 . Для того, чтобы подменить порт нужно указывать -port x в команде jhat

Также в составе JDK поставляется утилита jvisualvm - GUI приложение для просмотра файлов с дампом памяти.

Личные инструменты