Helper analyzers to simplify writing other analyzers
These are Standard analyzer modules that provide services available to other analyzer modules.
In practice, it is rare to implement a new analyzer module completely from scratch, using only the low-level
functions provided by the DTFJ library. On the contrary, we try to create new complex analyzers by
reusing and combining the functions provided by other pre-existing analyzers. Therefore, the dump analysis
tool comes with a library of basic analyzer modules that provide common functions that are often needed
when writing more complex analyzer modules. These common functions essentially create an extended SPI
that is available to anyone writing a new analyzer module.
This library of analyzer module building blocks is expected to grow steadily over time (it is in fact a main
goal of this tool to enable incremental contribution of new analysis functions). For the initial release, we
provide an initial core set. Here are some of the most commonly-used modules from that core set (refer to
the Javadoc for full details).
JVM-level 'helper' analyzers
The JVM-level 'helper' analyzers, in package com.ibm.dtfj.analyzer.jvm.helpers, provide a variety of
functions that essentially augment the low-level functions of the DTFJ interface for access to JVM-level
entities in the dump, or to simplify the use of the DTFJ functions. Key analyzers in this group include:
- OneJavaObject extends the functions provided by the low-level DTFJ JavaObject, in particular to
implement a standardized report showing the contents of an object, and to allow the look-up of
object fields by name, and accounting for superclasses.
- OneJavaClass extends the functions provided by the low-level DTFJ JavaClass in a way similar
to OneJavaObject. It provided standardized reporting, access to static fields, and special methods
to manipulate instances of java.lang.Class.
- OneJavaThread: extends the functions provided by the low-level DTFJ JavaThread, in particular
to implement standardized functions to print information about this thread in a report (e.g. print
the stack trace, print the memory layout), to keep track of native thread associated with this
JavaThread, and to correlate this thread with the JavaMonitors that it holds or is waiting on.
- AllJavaThreads: provides standardized functions to manipulate the collection of all JavaThreads
within one DTFJ JavaRuntime: produce a report listing all the threads, look-up a thread by its ID
or thread object, obtain a count of all threads, etc.
- AllJavaVMInitArgs: provide standardized functions to manipulate the collection of JVM
initialization arguments within one DTFJ JavaRuntime (DTFJ JavaVMInitArgs): produce a report
with that information, allow the look-up of individual arguments by name, etc.
- In general, there is one OneXXX type analyzer for each corresponding type in the DTFJ
interface, and one AllXXX type analyzer for each significant collection of DTFJ object types.
ObjectWrapper utilities
The ObjectWrapper utilities are a particular group of 'helper' analyzers (in package
com.ibm.dtfj.analyzer.helpers.objectwrapper), specifically designed to simplify building complex analyzers
that explore various Java™ data structures in the dump being analyzed (for example, data structures that are
part of the WebSphere® Application Server runtime). Key analyzers in this group include:
- ObjectFinder provides a fast look-up and count of any object instance or instances present in the
image, given a class name. It scans the entire heap to find the desired instances, and caches the
results for better performance.
- ClassFinder provides a fast lookup of any class currently loaded in the image, given a class name.
It scans the set of all class loaders to find the desired classes, and caches the results for better
performance. It also keeps track of subclasses of a given class, and implementations of a given
interface.
- ObjectWrapper is a further extension of OneJavaObject that generalizes the concept of an
analyzer that represents some instance of an object or other value extracted from the original
dump. An ObjectWrapper can represent not only an instance of an object, but also an instance of
a class (for access to the static fields of that class), or a primitive or String value that was extracted from
some field of some other object instance (itself represented by another ObjectWrapper). In
addition to simply 'wrapping' different kinds of objects and values, ObjectWrapper also provides
a set of utility methods to:
- Traverse a sequence of fields represented as a path expression to follow a chain of object
references starting at an initial object and find the value of a field in an object at the end
of the chain, with minimal code needed to handle each of the intermediate steps in the
path and for error handling
- Print the value of some field from the target object (or any object at the end of a complex
chain of references), using a variety of formats.
Therefore, ObjectWrapper is the main facility used to build analyzers that explore complex data
structures, such as the data structures used in the WebSphere Application Server runtime: you bootstrap from a first
ObjectWrapper representing some 'root' data structure, then navigate from that root to other data
structures, printing and checking values as needed to build a picture of the state of the runtime
being analyzed.
- ObjectWrapperCollection is a wrapper for a collection of ObjectWrapper analyzers that represent
all the instances of a given class currently present in the image. It facilitates writing concise code
to deal with singleton objects (when we can't in advance be sure if the object will be a singleton),
or situations where we explicitly want to iterate and report on all instances of a given object type.
- ListClassDefinitions, ListObjectInstances, ListObjectInstancesWithSubClasses are all
specializations of ObjectWrapperCollection to make it easier to build a list of all definitions of a
given class, all direct instances of a given class, and all instances of a given class or any of its
subclasses or implementations of a given interface, respectively. They are particularly intended for
use in building commands in the Jython interactive shell that is part of the Dump Analyzer tool,
but they can be invoked directly from other Java-based analyzers as well.
- LookupObjectByAddress is a specialization of ObjectWrapper to make it easier to find an object
instance given its address (not its class). Like the previous item, this analyzer is mostly intended
for use in the Jython interactive shell.
Wrappers for specific J2SE classes
The wrappers for J2SE classes, in package com.ibm.dtfj.analyzer.j2se.wrappers, are a collection of
specialized analyzer modules, all extending ObjectWrapper, each of which wraps a particular class from
the standard class library (such as java.util.Vector, java.util.Hashtable, etc.). Each wrapper encapsulates the
knowledge about the internal implementation of the J2SE class that it wraps, and provides methods that
other analyzer modules can use to access the contents of objects such as Vectors, Hashtables, etc. When
appropriate, these J2SE wrappers also implement the corresponding interface from the Java Collections
framework, when the underlying parent object from the dump being analyzed is itself a Collection. The
only difference between this Collection and the original one is that the elements of the Collection in the
Dump Analyzer tool are ObjectWrappers, rather than the original objects.
The set of J2SE wrappers is steadily expanding to represent the main classes encountered in most dumps
and needed to write complex analyzers such as WebSphere Application Server analyzers. Currently, J2SE wrappers are available for
most classes in the java.util.Collections framework.
See also: