end - Eclipse
Download
Report
Transcript end - Eclipse
TPTP Heap and Thread Profilers
High-level Design
Rev 1.0
Asaf Yaffe
July, 2006
Eclipse TPTP
Heap Profiler
Eclipse TPTP
Profiler Requirements
•
•
•
•
Track object allocations and de-allocations
Track GC events
Produce heap dumps on demand
Generate XML trace compatible with the
JVMPI Heap Profiler
Eclipse TPTP
Martini Requirements
• Generate the following events
–
–
–
–
Object Alloc
Object Free
GC Start
GC Finish
• Support the following data requests
– Get Object information (from an object id)
– Get Class information (from a class id)
– Get Reference graph for living objects (heap dump)
Eclipse TPTP
Martini Heap Events Overview
• Martini uses intra-function instrumentation for generating Object Alloc
events
• For all reference types except arrays, the Object Alloc event is generated
by instrumenting the constructor of the java.lang.Object class
– The instrumentation code passes the newly allocated object reference to a
Java static recorder function HeapProxy.ObjectAlloc which calls back into JPI
– JPI tags the allocated object (via JVMTI) in order for the JVM to identify the
object in the Object Free event
• communicated by the JVM via JVMTI
– This technique is sub-optimal but easy to implement
• Selectivity is implemented on Object Alloc event rather than during instrumentation
• May be optimized in future slices
• For array types, the Object Alloc event is generated by instrumenting
array allocation sites (i.e., after newarray, anewarray, multianewarray)
• The instrumentation activity takes place during CLASS_LOAD_HOOK
event of the java.lang.Object class or when heap events are dynamically
enabled by the tool
Eclipse TPTP
The HeapProxy Class
• Martini has a helper HeapProxy Java class
– Resides in a directory that is added to the JVM boot CLASSPATH during JPI
initialization
• The Problem: the HeapProxy recorder methods are defined as “native”
and are bound by JPI only during the JVM_INIT event (because JNI
services are not available before JVM_INIT)
– This is problematic since for some system classes, CLASS_LOAD_HOOK
events are sent before JVM_INIT
– Inserting calls to native methods before they are bound cause the JVM to
crash, even if these methods are never executed (just referencing these
methods in the code is enough to crash the JVM)
• The Solution: HeapProxy has wrapper functions which are always called
by instrumentation code that is inserted before JVM_INIT
– Those functions check whether the JVM has already been initialized and call
the native ObjectAlloc functions only after the JVM has been initialized
• i.e. object allocations before JVM_INIT after not communicated to the heap profiler
Eclipse TPTP
Object Alloc Event
• Event Source
– Regular Objects: BCI of java.lang.Object.<init>
– Arrays: BCI after callsites of newarray, anewarray, multianewarray
– Internal VM Allocations: JVMTI_EVENT_VM_OBJECT_ALLOC
• Data Items
–
–
–
–
–
Object ID
Class ID
Thread id (of the allocating thread)
Object Size
Whether this object is an array
• Selectivity
– By package/class
Eclipse TPTP
Object Free Event
• Event Source
– JVMTI_EVENT_OBJECT_FREE for tagged objects
• Data Items
– Object ID (easy - JVMTI)
– All other information is optional
• Can also be looked-up using a data request
• Selectivity
– By fully qualified class name
– Defined at Object Allocation time for both Object Alloc and Free
events
Eclipse TPTP
Garbage Collection Started
• Event Source
– JVMTI_EVENT_GARBAGE_COLLECTION_START
• Data Items
– None
• Selectivity
– None
• Notes
– Generated only for “stop-the-world” collections. Other collections are
not reported.
Eclipse TPTP
Garbage Collection Finished
• Event Source
– JVMTI_EVENT_GARBAGE_COLLECTION_FINISH
• Data Items
– None
• Selectivity
– None
• Notes
– See Garbage Collection Started
Eclipse TPTP
Heap Dump/Object References
• TBD…
Eclipse TPTP
Open Issues
• Heap Dump data
– Need more info about the following XML
fragments and their attributes:
• heapDumpDef
• gcRoot
• objectReference
• gcFinish element
– Are the following attributes used by the viewers:
usedObjects, usedObjSpace, totalObjSpace
Eclipse TPTP
Thread Profiler
Eclipse TPTP
Profiler Requirements
• Track Thread start and end events
• Track monitor events (critical sections, wait)
• Generate XML trace compatible with the
JVMPI implementation
Eclipse TPTP
Martini Requirements
• Generate the following events
–
–
–
–
–
–
Thread Start
Thread End
Contended Monitor Enter
Contended Monitor Entered
Monitor Wait
Monitor Waited
• Support the following data requests
– Get Object Monitor Usage information (from an object id)
– Get Thread information (from a thread id)
Eclipse TPTP
Thread Start Event
• Event Source
– JVMTI
• Data Items
–
–
–
–
Unique Thread ID
Thread Name
Parent Name
Group Name
• Selectivity
– None
Eclipse TPTP
Thread End Event
• Event Source
– JVMTI
• Data Items
– Thread ID
• Selectivity
– None
Eclipse TPTP
Contended Monitor Enter Event
• Event Source
– JVMTI
• Data Items
– Unique Monitor ID
– The waiting thread id
– The id of the thread owning the monitor
• Notes
– Other monitor information can be obtained with a data request:
• For contended monitors: a list of threads waiting for the monitor
• For “wait” monitors: a list of threads waiting to be notified
Eclipse TPTP
Contended Monitor Entered Event
• Event Source
– JVMTI
• Data Items
– Monitor ID
– The id of the thread that entered the monitor
• Selectivity
– None
Eclipse TPTP
Monitor Wait Event
• Event Source
– JVMTI
• Data Items
– Monitor ID
– The id of the waiting thread
– Wait timeout - the value passed to the obj.Wait() method
• Selectivity
– None
Eclipse TPTP
Monitor Waited Event
• Event Source
– JVMTI
• Data Items
– Monitor ID
– The id of the waiting thread
• Selectivity
– None
• Notes
– The <monWaited> output element includes the “timeout” attribute that
specifies the number of milliseconds the thread had to wait for the
monitor.
– This data item is not available in JVMTI so the profiler will have to
calculate it manually
Eclipse TPTP
Backup
Eclipse TPTP
HeapProxy Java Class
public class HeapProxy
{
private static int m_bJVMInit = 0;
public static void JVMInit()
{ m_bJVMInit = 1; }
public static native void ObjectAlloc(java.lang.Object obj);
public static void EarlyObjectAlloc(java.lang.Object obj)
{
if (m_bJVMInit != 0) ObjectAlloc(obj);
}
public static native void ArrayAlloc(java.lang.Object arr);
public static void EarlyArrayAlloc(java.lang.Object arr)
{
if (m_bJVMInit != 0) ArrayAlloc(obj);
}
}
Eclipse TPTP
Instrumenting java.lang.Object Constructor
Before
public Object()
{
}
Best seen in
Slide Show mode
After
public Object()
{
HeapProxy.EarlyObjectAlloc(this);
}
Martini inserts a call to
HeapProxy.EarlyObjectAlloc, because the
insertion will always happen before the VM is
initialized, and we cannot use native methods
because they were not bound yet.
Eclipse TPTP
Instrumenting Array Allocation Callsites
[case 1 – before JVM_INIT event received]
Before
After
void someMethod()
void someMethod()
{
{
…
…
…
…
int[] intArray =
int[] intArray =
new int[20];
new int[20];
Best seen in
Slide Show mode
…
HeapProxy.EarlyArrayAlloc(intArray);
…
…
}
…
}
Eclipse TPTP
Martini inserts a call to
HeapProxy.EarlyArrayAlloc. Since the JVM has
not been initialized yet, we cannot use native
methods because they were not bound yet.
Instrumenting Array Allocation Callsites
[case 2 – after JVM_INIT event received]
Before
After
void someMethod()
void someMethod()
{
{
…
…
…
…
int[] intArray =
int[] intArray =
new int[20];
new int[20];
…
HeapProxy.ArrayAlloc(intArray);
…
…
}
…
}
Eclipse TPTP
Best seen in
Slide Show mode
Martini inserts a call to
HeapProxy.ArrayAlloc. Since the JVM has already
initialized, we can safely use native methods
because they were already bounded.
Heap Instrumentation Overview
• Instrumenting the java.lang.Object constructor:
– Add references to the HeapProxy class and the
HeapProxy.EarlyObjectAlloc function to the constant pool
– Modify the method’s code attribute and inject code to call the
HeapProxy.EarlyObjectAlloc function.
• Instrumenting array allocation sites in a Java class:
– Add references to the HeapProxy class and the HeapProxy.ArrayAlloc
or HeapProxy.EarlyObjectAlloc functions to the constant pool
– Iterate over the class methods, and for each method that can be
instrumented (i.e. has a “code” attribute)
• Search for any of the following array allocation instructions: newarray,
anewarray, multianewarray.
• If found, modify the method’s code attribute and inject code after each
allocation site to call the HeapProxy.ArrayAlloc function.
Eclipse TPTP
java.lang.Object Constructor Instrumentation Details
Original method code
Instrumented method code
The ‘this’ pointer of the newly allocated object is
stored in.start
local variable 0. Load it to the operand
stack so it can be passed to the EarlyObjectAlloc
static function
.start
aload_0
return
invokestatic EarlyObjectAlloc()
.end
return
Legend
.start
pseudo-instructions
inst1
original instructions
sipush
.end
new instructions
Eclipse TPTP
Array Allocation Site Instrumentation Details
Original method code
.start
.start
inst
inst
After the ‘newarray’ instruction, a reference to the
newly allocated array is on the operand stack. The
reference
instis duplicated and sent to the ArrayAlloc
or EarlyArrayAlloc static function
inst
newarray
newarray
inst
dup
inst
invokestatic [Early]ArrayAlloc()
.end
inst
Legend
.start
pseudo-instructions
inst1
original instructions
sipush
inst
new instructions
.end
Eclipse TPTP
Instrumented method code