Как использовать датчики HotSpot DTrace в SmartOS?
В Mac OS X я могу найти пробы HotSpot для запуска программ Java, запустив:
cody.mello@ashur ~ (1) % sudo dtrace -ln 'hotspot*:::'
Password:
Invalid connection: com.apple.coresymbolicationd
ID PROVIDER MODULE FUNCTION NAME
165084 hotspot46 libjvm.dylib _ZN13instanceKlass15initialize_implE19instanceKlassHandleP6Thread [instanceKlass::initialize_impl(instanceKlassHandle, Thread*)] class-initialization-clinit
165085 hotspot46 libjvm.dylib _ZN13instanceKlass15initialize_implE19instanceKlassHandleP6Thread [instanceKlass::initialize_impl(instanceKlassHandle, Thread*)] class-initialization-concurrent
165086 hotspot46 libjvm.dylib _ZN13instanceKlass15initialize_implE19instanceKlassHandleP6Thread [instanceKlass::initialize_impl(instanceKlassHandle, Thread*)] class-initialization-end
165087 hotspot46 libjvm.dylib _ZN13instanceKlass15initialize_implE19instanceKlassHandleP6Thread [instanceKlass::initialize_impl(instanceKlassHandle, Thread*)] class-initialization-erroneous
165088 hotspot46 libjvm.dylib _ZN13instanceKlass15initialize_implE19instanceKlassHandleP6Thread [instanceKlass::initialize_impl(instanceKlassHandle, Thread*)] class-initialization-error
165089 hotspot46 libjvm.dylib _ZN13instanceKlass15initialize_implE19instanceKlassHandleP6Thread [instanceKlass::initialize_impl(instanceKlassHandle, Thread*)] class-initialization-recursive
...
Но если я создам простую Java-программу и запускаю ее на SmartOS:
cody@101901c9-6d66-ea32-fe42-f1fbebd4bf99 ~ % cat Loop.java
class Loop {
public static void main(String[] args) throws InterruptedException {
while (true) {
Thread.sleep(5000);
}
}
}
cody@101901c9-6d66-ea32-fe42-f1fbebd4bf99 ~ % javac Loop.java
cody@101901c9-6d66-ea32-fe42-f1fbebd4bf99 ~ % java Loop
Я не могу найти никаких зондов:
cody@101901c9-6d66-ea32-fe42-f1fbebd4bf99 ~ (255) % pfexec dtrace -ln 'hotspot*:::'
ID PROVIDER MODULE FUNCTION NAME
dtrace: failed to match hotspot*:::: No probe matches description
Что-нибудь особенное, что мне нужно сделать, чтобы увидеть их?
1 ответ
Проблема здесь в том, что на SmartOS (и других вариантах illumos - а также их проприетарных собратьях Solaris) модуль DTrace в JVM загружается лениво (то есть DOF был скомпилирован с -x lazyload
). В результате зонды DTrace не загружаются, пока не будут явно включены. Есть два способа справиться с этим. Во-первых, вы можете указать DTrace самому включить определенные тесты, заставляя целевой процесс загружать свои тесты. Для этого требуется (как минимум) идентификатор целевого процесса; чтобы описать это в примере, приведенном в вопросе, это будет что-то вроде:
% pfexec dtrace -ln 'hotspot*$target:::' -p `pgrep -fn "java Loop"`
Это подхватит hotspot
(а также hotspot_jni
) USDT проверяет, но все еще оставляет использование jstack()
трудное действие на машине, заполненной ничего не подозревающими процессами Java. (То есть это работает, когда вы хотите использовать зонды USDT в известном процессе, а не когда вы хотите использовать профиль помощника ustack для всех процессов Java.) Если это проблема, которая вас волнует, в вариантах illumos (SmartOS, OmniOS и т. Д.) Вы можете эффективно отменить ленивую загрузку зондов DTrace (и помощника по стеку) с помощью библиотеки аудита, разработанной для этой задачи. Эта библиотека - /usr/lib/dtrace/libdtrace_forceload.so
и его 64-битный вариант, /usr/lib/dtrace/64/libdtrace_forceload.so
- эффективно заставит датчики DTrace загружаться при запуске процесса, давая вам зонды USDT и jstack()
действие для всех таких процессов. Чтобы сделать это для 32-битных JVM, запустите java
с LD_AUDIT_32
набор переменных среды:
export LD_AUDIT_32=/usr/lib/dtrace/libdtrace_forceload.so
Для 64-битных JVM:
export LD_AUDIT_64=/usr/lib/dtrace/64/libdtrace_forceload.so