Як простежити java-програму?


25

Як sysadmin я іноді стикаюся з ситуаціями, коли програма поводиться ненормально, при цьому зовсім не створюючи помилок або створюючи дурницькі повідомлення про помилки.

У минулому - до появи яви - було два контрзаходи:

  1. Якщо нічого іншого не допомагає - RTFM ;-)
  2. Якщо навіть 1. не допомагає - простежте за системою-дзвінками і подивіться, що відбувається

Я зазвичай використовую strace -fдля цього завдання з Linux (інші ОС мають подібні інструменти простеження). Тепер, хоча це зазвичай добре працює для будь-якої старомодної програми, слід стає дуже нечітким, коли робити те саме на Java -процесі. Системні дзвінки, схоже, не пов'язані з жодними реальними діями, що страшно шукати такий смітник.

Чи є кращі способи зробити це (якщо вихідний код недоступний)?

Відповіді:


16

Як згадував ckhan, jstackвін чудовий тим, що дає повний слід стека всіх активних потоків у JVM. Те ж саме можна отримати на stderr JVM за допомогою SIGQUIT.

Іншим корисним інструментом є те, jmapщо може схопити звалище з процесу JVM, використовуючи PID процесу:

jmap -dump:file=/tmp/heap.hprof $PID

Цей visualvmнакопичувальний накопичувач може бути завантажений у такі інструменти (що зараз є частиною стандартної установки Oracle java sdk під назвою jvisualvm). Крім того, VisualVM може підключатися до запущеного JVM та відображати інформацію про JVM, включаючи показ графіків внутрішнього використання процесора, кількості потоків та використання купи - відмінно підходить для відстеження витоків.

Інший інструмент, jstat- може збирати статистику збору сміття для JVM протягом певного періоду часу, подібно до vmstat при запуску з числовим аргументом (наприклад vmstat 3).

Нарешті, можна використовувати Агент Java для просування інструментарію для всіх методів усіх об'єктів під час завантаження. Бібліотека javassistможе допомогти зробити це дуже просто. Отже, можливо додати власну кальку. Важкою частиною цього є пошук способу отримати вихідний слід лише тоді, коли ви цього хотіли, а не весь час, що, швидше за все, сповільнить JVM до сканування. Існує програма під назвою, dtraceяка працює таким чином. Я спробував це, але не дуже вдало. Зауважте, що агенти не можуть інструментувати всі класи, тому що ті, які потрібні для завантаження JVM, завантажуються до того, як агент може інструментувати, і тоді вже пізно додати інструментарій до цих класів.

Моя пропозиція - почніть з VisualVM і подивіться, чи це говорить вам про те, що вам потрібно знати, оскільки він може показувати поточні потоки та важливу статистику для JVM.


До речі, це дивовижне питання; Я сподіваюся, що більше людей додають відповіді з іншими ідеями. Коли я багато років просив людей, які працюють з Явою, про те, як простежити, вони видавали мені порожні погляди. Можливо, вони просто не знають дивовижної напруги.
попіл

10

Так само марно під час налагодження програм, які зійшли з ладу в системі Linux, ви можете використовувати подібні інструменти для налагодження запущених JVM у вашій системі.

Інструмент №1 - jvmtop

Як і у jvmtoptop , ви можете використовувати jvmtop, щоб побачити, до яких класів належить виконана JVM у вашій системі. Після встановлення ви викликаєте його так:

$ jvmtop.sh

Його результат аналогічний стилю, щоб виглядати як інструмент top:

 JvmTop 0.8.0 alpha   amd64  8 cpus, Linux 2.6.32-27, load avg 0.12
 http://code.google.com/p/jvmtop

  PID MAIN-CLASS      HPCUR HPMAX NHCUR NHMAX    CPU     GC    VM USERNAME   #T DL
 3370 rapperSimpleApp  165m  455m  109m  176m  0.12%  0.00% S6U37 web        21
11272 ver.resin.Resin [ERROR: Could not attach to VM]
27338 WatchdogManager   11m   28m   23m  130m  0.00%  0.00% S6U37 web        31
19187 m.jvmtop.JvmTop   20m 3544m   13m  130m  0.93%  0.47% S6U37 web        20
16733 artup.Bootstrap  159m  455m  166m  304m  0.12%  0.00% S6U37 web        46

Інструмент №2 - jvmmonitor

Ще одна альтернатива - використовувати jvmmonitor . JVM Monitor - це програма Java, інтегрована з Eclipse для контролю процесора, потоків та використання пам'яті програм Java. Ви можете або використовувати його для автоматичного пошуку запущених JVM в localhost, або він може підключитися до віддалених JVM, використовуючи порт @ хост.

ss jvmmonitor

Інструмент №3 - visualvm

visualvm - це, ймовірно, "інструмент", до якого слід звернутися при налагодженні проблем із JVM. Його набір функцій досить глибокий, і ви можете дуже глибоко переглянути внутрішні.

Продуктивність роботи програми або аналіз розподілу пам'яті:

ss visualvm №2

Візьміть та покажіть відвали ниток:

ss visualvm # 3

Список літератури


4

Розглянемо jstack. Не зовсім збіг для strace, більше - pstackаналог, але, принаймні, дасть вам картинку з часом. Не могли б ви вступити разом, щоб отримати сирий слід, якщо вам доведеться.

Дивіться також пропозиції в цій статті про ТА: /programming/1025681/call-trace-in-java


2

Якщо ви використовуєте RHEL OpenJDK (або подібний, справа в тому, що це не JDK Oracle), ви можете використовувати SystemTap для цього.

Деякі датчики включені за допомогою опції командного рядка Java -XX:+DTraceMethodProbes, -XX:+DTraceAllocProbes, -XX:+DTraceMonitorProbes. Зауважте, що включення цих зондів суттєво вплине на ефективність програми.

Ось приклад SystemTap Script:

#!/usr/bin/stap

probe hotspot.class_loaded {
    printf("%12s [???] %s\n", name, class);
}

probe hotspot.method_entry, 
      hotspot.method_return {
    printf("%12s [%3d] %s.%s\n", name, thread_id, class, method);
}

probe hotspot.thread_start, 
      hotspot.thread_stop {
    printf("%12s [%3d] %s\n", name, id, thread_name);
}

probe hotspot.monitor_contended_enter, 
      hotspot.monitor_contended_exit {
    printf("%12s [%3d] %s\n", name, thread_id, class);
}

Ви також можете використовувати, jstack()щоб отримати стек Java процесу, але він буде працювати лише в тому випадку, якщо ви запустите SystemTap перед JVM.


Зауважте, що SystemTap відстежує кожен метод. Він також не в змозі отримати аргументи методу. Іншим варіантом є використання власних можливостей трасування JVM, яке називається JVMTI. Однією з найвідоміших реалізацій JVMTI є BTrace .


0

Вам рекомендується спробувати Jackplay , який є інструментом трасування JVM, який дозволяє відстежувати введення методу та вихід без зміни коду чи перерозподілу.


Ви не можете приєднати його до запущеного JVM. Крім цього - цікавий інструмент
Нілс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.