Object allocation tracing / profilers

Jeremy Manson jeremymanson at google.com
Fri Feb 7 01:13:16 UTC 2014


You aren't doing anything wrong.  More detail:

- Anything bytecode based (like my instrumenter, which you tried) isn't
going to let you know what has been escape analyzed away.  You can only do
bytecode rewriting before escape analysis runs, and before the escape
analysis runs, there is no way to find out what will be escape analyzed
away.

- A bytecode-based instrumenter will also not pick up allocations that
occur via JNI, which is the problem that VMObjectAlloc solves.

- If you happen to be on a platform that supports it, and you've compiled
the JDK correctly, you can use dtrace to capture Java allocations.

- Because of its limitations and performance issues, we've actually stopped
doing bytecode-based instrumentation at Google in favor of instrumenting
the VM directly.  We now use JVMTI-style callbacks whenever an allocation
happens.  If people are interested, I can provide the patch (in fact, I
forward ported it to JDK8 yesterday!), but it is rather user unfriendly, so
you have to be rather ambitious to use it.  On the plus side, it can take
into account escape analyzed objects (right now, it doesn't instrument
them, but this could conceivably be changed).

- On the down side, if you take this approach, you can't call back into
Java from the JVM callbacks.  This is because calling back into Java may
require the JVM to come to a safepoint, which you can't do in the middle of
allocation (which is where the callback would occur).

Jeremy



On Thu, Feb 6, 2014 at 2:36 PM, Robert Stupp <snazy at snazy.de> wrote:

> Hi,
>
> I'm trying to trace/count object allocations - especially regarding the
> ObjectIn/OutputStream stuff.
>
> I know two API points: JVMTI and instrumentation. JVMTI fires an event for
> nearly everything except allocations from bytecode - instrumentation allows
> to transform bytecode (e.g. to issue a callback on object allocation).
>
> But I am not very satisfied - maybe I oversee something...
> What I need is the number of "real" allocations. I do not want to count
> allocations that Hotspot would normally eliminate - for example Hotspot
> seems to eliminate instances of ArrayList$Itr under some circumstances.
>
> I played around with this instrumentation code:
> https://code.google.com/p/java-allocation-instrumenter/
> But this one and any other profiler (JProfiler) I tried always gave me the
> theoretical number of instances of ArrayList$Itr. This reason seems to be
> as follows:
> With instrumentation/transformation constructors get a piece of code
> "injected" which calls a "profile object allocation method". This method
> gets the new object instance, which is used to get the Class object and to
> inquire the shallow object size on the heap - and it gets the current
> thread's stack trace.
>
> My suggestion is, that Hotspot cannot eliminate object allocations (for
> example of ArrayList$Itr) because the profiler bytecode needs that object
> instance and does other things, that are "strange" to Hotspot.
>
> I hoped that I can get callbacks using JVMTI but due to the restrictions
> mentioned here (
> http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#VMObjectAlloc)
> there are no callbacks for allocations caused by bytecode.
> VMObjectAlloc events occur during the start and end of the application -
> but not a single event is fired while the application is running (I've
> attached my JVMTI code).
>
> Am I doing anything wrong? Is there a possibility to count only the "real"
> instances? If not, wouldn't it be nice to have such a functionality in
> JVMTI or a callback functionality for
> http://download.java.net/jdk8/docs/api/java/lang/instrument/Instrumentation.html
> ?
> My fear is that all profiler results that all developers see are
> inaccurate because the code injected by profilers influences Hotspot too
> much.
>
> -
> Robert
>
>



More information about the core-libs-dev mailing list