2016-03-22 14 views
7

Unter Mac OS X kann ich die HotSpot-Sonden der laufenden Java-Programme, indem Sie finden:Wie verwende ich die HotSpot DTrace-Sonden auf SmartOS?

[email protected] ~ (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 
... 

Aber wenn ich ein einfaches Java-Programm erstellen und auf SmartOS laufen:

[email protected] ~ % cat Loop.java 
class Loop { 

    public static void main(String[] args) throws InterruptedException { 
     while (true) { 
       Thread.sleep(5000); 
     } 
    } 
} 
[email protected] ~ % javac Loop.java 
[email protected] ~ % java Loop 

ich kann Finde keine Sonden:

[email protected] ~ (255) % pfexec dtrace -ln 'hotspot*:::' 
    ID PROVIDER   MODULE       FUNCTION NAME 
dtrace: failed to match hotspot*:::: No probe matches description 

Gibt es etwas Besonderes, das ich tun muss, um sie zu sehen?

Antwort

15

Das Problem hierbei ist, dass auf SmartOS (und andere Illumos Varianten - sowie ihre proprietären Solaris Cousins) die DTrace-Modul in der JVM träge ist geladen (das heißt, wurde die DOF mit -x lazyload kompiliert). Daher werden die DTrace-Tests erst geladen, nachdem sie explizit aktiviert wurden. Es gibt zwei Möglichkeiten, damit umzugehen. Die erste besteht darin, dass Sie DTrace selbst anweisen können, die betreffenden spezifischen Prüfpunkte zu aktivieren und den Zielprozess zum Laden seiner Prüfpunkte zu zwingen. Dies erfordert (mindestens) die ID des Zielprozesses; diese im Beispiel Couch in der Frage zur Verfügung gestellt, wäre es so etwas wie:

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

Das die hotspot abholen (und hotspot_jni) USDT Sonden, aber es bleibt immer noch die jstack() Aktion schwierig auf einer Maschine gefüllt mit ahnungslosen Java-Prozessen. (Das heißt, das funktioniert, wenn Sie die USDT-Probes in einem bekannten Prozess verwenden möchten, nicht wenn Sie das ustack-Hilfsprofil alle Java-Prozesse verwenden möchten.) Wenn Sie ein Problem haben, das Ihnen wichtig ist, OmniOS, etc.) können Sie das verzögerte Laden der DTrace-Probes (und des Stack-Helpers) effektiv rückgängig machen, indem Sie eine Audit-Bibliothek verwenden, die für die Aufgabe entwickelt wurde. Diese Bibliothek - /usr/lib/dtrace/libdtrace_forceload.so und ihre 64-Bit-Variante, /usr/lib/dtrace/64/libdtrace_forceload.so - erzwingt effektiv, dass die DTrace-Probes geladen werden, wenn der Prozess startet, wodurch Sie USDT-Probes und die Aktion jstack() für alle diese Prozesse erhalten. Um dies zu tun für 32-Bit-JVMs, starten java mit dem LD_AUDIT_32 Umgebungsvariable Set:

export LD_AUDIT_32=/usr/lib/dtrace/libdtrace_forceload.so 

Für 64-Bit-JVMs:

export LD_AUDIT_64=/usr/lib/dtrace/64/libdtrace_forceload.so