X

Sundararajan's Weblog

  • Java
    October 5, 2005

Permanent generation analysis with OQL

Guest Author

Java permanent generation
holds holds data needed by the virtual machine to describe objects that do not
have an equivalence at the Java language level. For example objects describing classes and
methods are stored in the permanent generation.

Let us see how OQL
to analyze/understand Java permanent generation. Before proceeding, generate a sample heap dump. I created a sample heap dump from a Tomcat webserver instance on Solaris/sparc using jmap.

Let us ask few questions and try to answer those by OQL:



How many classes loaded in my app?


select count(heap.classes())

We use the classes method of heap object and used count built-in
to count the result of the same. The output was: 1950

How many of it bootstrap (i.e., Java platform classes loaded
by JVM without using any java.lang.ClassLoader instance)?



select count(heap.classes(), 'it.loader == null')

Note that we use a filter condition "it.loader == null". The output
for this query was 1327. i.e., out of 1950 classes, 1327 are really bootstrap
classes. Note that once loaded bootstrap classes are never unloaded (unlike
other classes which could be unloaded if the classloader is dead. In other words,
bootstrap loader is always alive)

Show each class loader and number of classes loaded by it

    
select { loader: cl, count: cl.classes.elementCount }
from instanceof java.lang.ClassLoader cl

Here we select multiple values for each loader (loader and count of
classes) and so we use JavaScript object literal. instanceof
keyword is used so that objects of all subclasses of java.lang.ClassLoader
are selected. java.lang.ClassLoader has a private field of name 'classes'
and of type java.util.Vector. This holds the classes loaded by it. We access
the vector from each loader and print the count from it (elementCount as you'd
expect is a private field of java.util.Vector class).

Show each loader and it's parent loader



ClassLoader
instances form a parent-child chain. i.e, each loader
can optionally hava a parent loader (or null). You may want to know parent
loader of each loader:
 
select { loader: cl, parent: cl.parent }
from instanceof java.lang.ClassLoader cl

As you'd have guessed, 'parent' is private field of java.lang.ClassLoader
that points to the parent loader.

Show entire child-parent chain for each loader


select map(heap.objects('java.lang.ClassLoader'),
function(it) {
var res='';
while (it != null) {
res += toHtml(it) + "->";
it = it.parent;
}
res += "null";
return res + "<br>";
})

Here we use map built-in to call a function (defined inline) on each
class loader instance. The function returns a HTML string by walking all
child-parent chain by a while-loop.

Show each loader and number of classes loaded by it -- but show it
as a histogram (sort it by count of classes loaded)


select map(sort(map(heap.objects('java.lang.ClassLoader'),
'{loader: it, count: it.classes.elementCount }'), 'lhs.count < rhs.count'),
'toHtml(it) + "<br>"')

Explanation of the above query is left as exercise to reader :-)
Show each loader and classes loaded by it


select { loader: cl,
classes: filter(map(cl.classes.elementData, 'it'), 'it != null') }
from instanceof java.lang.ClassLoader cl

As mentioned earlier, classes Vector has elementData array that holds
the loaded classes. We filter null entries in it by filter built-in (note
that a Vector can have more space allocated for possible future expansion.
These slots will have nulls)

Show different types of ClassLoaders in the system. i.e., show different
ClassLoader classes


select unique(map(heap.objects('java.lang.ClassLoader'), 'classof(it)'))

Here we use unique built-in function to find unique classes of java.lang.ClassLoader
instances.

How many classes were generated for reflection speed-up?


Hotspot JVM generates classes on-the-fly to speed up Java reflective calls (Constructor.newInstance, Method.invoke etc.). We want to find out how many
such classes were generated. Piece of implementation detail before proceeding:
All reflection speed-up classes are loaded by classloaders of type
sun.reflect.DelegatingClassLoader. Each such loader only loads a single class.

select count(heap.objects('sun.reflect.DelegatingClassLoader'))

Output for my Tomcat instance was 52. So, 52 classes were generated for reflection
speedup.

Show liveness paths for each class loader

A Class are alive till the classloader that loaded it is alive. Let us say,
you want to find out why your classloaders are live -- i.e, show all chain of
references by which it is alive.

select { loader: cl, liveness: heap.livepaths(cl) }
from instanceof java.lang.ClassLoader cl

We have seen few OQL queries. One thing we missed: the output for these
queries! The output from jhat will have hyperlinks. You can navigate Java
objects,classes from query output objects easily. If you have still not downloaded
Mustang, please do it now and play
with jhat and do let us know your suggestions/comments!

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.