如何在SmartOS上使用HotSpot DTrace探针?

时间:2016-03-22 22:57:16

标签: java dtrace smartos

在Mac OS X上,我可以通过运行以下命令找到运行Java程序的HotSpot探针:

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 个答案:

答案 0 :(得分:15)

这里的问题是,在SmartOS(和其他illumos变体 - 以及它们的专有Solaris表兄弟)上,JVM中的DTrace模块是延迟加载(也就是说,DOF是用-x lazyload)。因此,在显式启用之前,不会加载DTrace探测器。有两种方法可以解决这个问题。首先,您可以告诉DTrace本身启用相关的特定探测器,强制目标进程加载其探测器。这需要(至少)目标进程的ID;在问题中提供的示例中,这可能是:

% pfexec dtrace -ln 'hotspot*$target:::' -p `pgrep -fn "java Loop"`

这将获取hotspot(和hotspot_jni)USDT探测器,但在充满毫无疑问的Java进程的计算机上仍然难以使用jstack()操作。 (也就是说,当您想在已知进程上使用USDT探测器时,这种方法有效,而不是在您希望在所有Java进程中使用ustack帮助程序配置文件时。)如果这是您关心的问题,请使用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