Improve root set used by hat
A. Sundararajan
Sundararajan.A at Sun.COM
Tue Oct 6 23:28:37 PDT 2009
I agree. Static fields of classes loaded by non-bootstrap loaders should
not be part of root set.
PS. I am not sure if this is a bug with hat or with heap dumpers (the
hotspot built-in dumper and SA's dumper). I don't remember how "roots"
is filled. May be, these static fields should not be flagged as roots?
-Sundar
Kelly O'Hair wrote:
> CC to the serviceability-dev alias.
>
> ---
>
> I have no objection to this change, anybody else care? Sundar? Alan?
> If not I can file a bug, and we can decide who gets to push the change
> into jdk6, and probably jdk7 too.
>
> -kto
>
> Keith Randall wrote:
>> I'm working on tracing down a ClassLoader leak in a web application
>> I'm working on (see
>> http://blogs.sun.com/fkieviet/entry/classloader_leaks_the_dreaded_java
>> for a description of the kind of leak I'm talking about). I'm using
>> hat to find sources of the leak, and I have run into a problem where
>> hat generates a lot of false positives of a particular form. When I
>> list the reference chains from the rootset for a ClassLoader, it
>> lists lots of chains which start at a static field of a class which
>> was loaded by that classloader. This isn't a real leak, however,
>> because if the ClassLoader is otherwise dead, the class containing
>> that static field will be GCed.
>>
>> I propose that hat shouldn't consider static fields of classes which
>> aren't loaded by the root classloader as GC roots. These roots will
>> be found during the normal heap walk (classloader -> class -> static
>> field). Unless of course the classloader isn't reachable, but that
>> is exactly when we don't want to consider static fields in these
>> classes as roots.
>>
>> Does this sound like a reasonable thing to do? It works for me, just
>> want to make sure it won't break some other use case for hat.
>>
>> Possible patch (to openjdk6 build b16):
>>
>> --- com/sun/tools/hat/internal/model/Snapshot.java
>> ** 331,336 ****
>> --- 331,345 ----
>> System.out.println();
>> for (Root r : roots) {
>> r.resolve(this);
>> + if (r.getType() == Root.JAVA_STATIC) {
>> + JavaClass clazz = (JavaClass) r.getReferer();
>> + if (clazz.getLoader() != nullThing) {
>> + // this "root" will be discovered through a
>> reference
>> + // to its classloader, so we don't need to
>> treat it as
>> + // an explicit root.
>> + continue;
>> + }
>> + }
>> JavaHeapObject t = findThing(r.getId());
>> if (t != null) {
>> t.addReferenceFromRoot(r);
>>
More information about the serviceability-dev
mailing list