This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: Java profiling with systemtap
- From: Mark Wielaard <mjw at redhat dot com>
- To: "Frank Ch. Eigler" <fche at redhat dot com>
- Cc: Peter Süttner <Peter dot Suettner at mailbox dot tu-dresden dot de>, systemtap at sourceware dot org
- Date: Mon, 03 Jan 2011 12:09:33 +0100
- Subject: Re: Java profiling with systemtap
- References: <4D0630F6.3060803@mailbox.tu-dresden.de> <y0msjy03ywf.fsf@fche.csb>
On Tue, 2010-12-14 at 15:03 -0500, Frank Ch. Eigler wrote:
> > 1. To trace methods in Java, -XX+ExtendedDTraceProbes flag needs to be
> > set at JVM start up. They have a very high overhead, since probes
> > seem to fire at every method call (and there are really a lot of them)
> > made within the JVM process. I couldn't find a way to filter for
> > specific method. Any suggestions?
>
> Apparently, the Sun JVM instrumentation doesn't make this possible:
> there is only one sdt.h-based activateable probe for all method
> entries, and another one for exits. Filtering after the fact is
> indeed gross.
>
> I believe the JVMTI run-time APIs allow more fine-grained control,
> akin to your bytecode-rewriting work, but that is not accessible to
> systemtap at this time.
You can register a jvmti agent (library) with the JVM and register
MethodEntry or Breakpoint handler callbacks and then write a tapset that
probes your callback functions. (Note that installing a jvmti agent does
have some overhead, but not as much as intercepting each and every
method entry/exit.)
> It may be possible to have the JVM JIT expose data about the compiled
> functions, and nominate for them individual breakpointable addresses
> that e.g. systemtap could use, but this is a large chunk of work.
Yes, the probes for this are already there:
/* hotspot.compiled_method_load
Triggers when a compiled method is loaded.
Sets class to the name of the class, method to the name of the
method, sig to the signature string of the method, code to the
address where the code is loaded and size to the number of bytes of
code.
*/
/* hotspot.compiled_method_unload
Triggers when a compiled method is unloaded.
Sets class to the name of the class, method to the name of the
method, sig to the signature string of the method.
*/
So, you can intercept these and register/unregister the native code
addresses and then probe those. But doing this automagically from
systemtap would mean having dynamically registering new probe handlers
while already running a stap script. Which is not a trivial addition to
the systemtap runtime (although it would be a fun [and useful] one to
have). (This doesn't take into account that methods are not always
compiled, so you are then missing the interpreted method calls.)
> > So far, I am using a workaround. I am using bytecode instrumentation
> > to inject something like
> > 'System.out.println("Package.Class.Methodname.method_entry")' at
> > method entry,
> > and
> > 'System.out.println("Package.Class.Methodname.method_exit")' at method
> > return (only for methods we are interested in)
> > This causes a write() syscall and it's argument is parsed in a
> > systemtap script. In combination with the TID, it should be possible
> > to connect specific resource usage to the currently executed
> > method. That way I can keep track of a specific subset of methods and
> > it is still independent of a specific JVM.
>
> A clever hack, and for now, it may be about the best one can do.
If you go this route then you might want to take a look at byteman
<http://www.jboss.org/byteman> which facilitates a lot of bytecode
injection tricks.
Cheers,
Mark