Elephant Tracks is a garbage collection tracing tool for java programs. For an arbitrary java program, it will produce a trace file with the following features:
Elephant tracks uses a combination of bytecode rewriting and JVM callbacks. The ET bytecode rewriter is written in Java using the ASM bytecode analysis and transformation library. Download verion 3.1 of the ASM jar file. JVM callbacks are implemented in C++ as a JVMTI (JVM Tool Interface) agent. The agent is compiled as a dynamic library (a .so) and loaded by the JVM at runtime (see "Running ET" below).
To build the system, first edit Makefile.inc and set the various variables appropriately. INSTALL_DIR should refer to a directory that will hold the ET bytecode rewriter jar file and the JVMTI agent .so -- this directory needs to be accessible when the tool is run. ASMJAR and JAVA_PATH should point the ASM jar file and the local Java installation, respectively. Use "make all" followed by "make install" to compile, link, and copy the jar file and .so to the install directory.
On x86_64 you will need to make sure CXXFLAGS and CFLAGS contains the -fPIC option.
java -classpath <other-paths>:$ASMJAR -Xbootclasspath/a:$INSTALL_DIR \ -agentlib:ElephantTracks=javaPath=$JAVA_PATH:traceFile=<tracefilename>:namesFile=<namesFile>:classReWriter=$INSTALL_DIR/elephantTracksRewriter.jar \ <class-to-run> <rest-of-args>Some version of ASM seem to cause trouble, so I've uploaded a known to work jar here.
Turns on the optimized version of the byte code instrumenter. Doesn't make things go much faster, but will inject fewer byte codes, which is useful if so many are injected that the limit is exceeded (needed to run the full dacapo suite).
The trace file produced by Elephant tracks consists of a sequence of events, one per line, in time order. Each entry begins with a single character that indicates the type of event, followed by one or more arguments. Numeric arguments are all in hex (without the "0x").
Note: thread IDs need not have any special meaning, but in ET they happen to be the object IDs of the corresponding java.lang.Thread objects.
A <object-id> <size> <type> <thread-id>
The new object has ID object-id, which is used to refer to the object in later events; the size in bytes; the type (a Java type as a string); the ID of the allocating thread.
D <object-id>
U <old-target-id> <object-id> <new-target-id><thread-id>
A field (currently, unspecified) in the object with ID object-id is changed from pointing to old-target-id to point to new-target-id, and this occured in thread-id.
An object-id of 0 indiacates that this is an update to a static field.
M <method-id> <receiver-object-id> <thread-id>
A call to the method method-id with receiver object receiver-object-id in thread thread-id.
A origin receiver of 0 indicates that this was a static method
E <method-id> <receiver-object-id> <thread-id>
Return from method method-id with receiver object receiver-object-id in thread thread-id.
A receiver of 0 indicates this was a static method.
N <method-id> <class-name> <method-name> <signature>
F <I|S> <fieldId> <name> <classId> < className> <desc>
C <class-id> <class-name> <super-id>
I <class-id>