Sunday, April 1, 2012

Extract system properties from heap dump using Visual VM OQLand JavaScript

VisualVM is one of the great tool but still it's not popular in Java community.

One of the interesting feature of VisualVM is traversing heap dump. VisualVM supports OQL syntax similar to eclipse MAT. But java script support along with OQL sytax make it different.

Do you want to print system properties from heap dump? System Properties are internally maintained as hash Map. It's probably difficult to traverse such hash map using normal OQL syntax. But using VisualVM OQL syntax along with java script it's possible.

Load heap dump in visualVM and copy paste below javascript syntax into VisualVM -> HeapDump -> OQL Console (tab).

function printProp(obj) {
    var ret = '';
        // count is proeprty of java.util.Properties 
        ret = 'Count = '+obj.count+"< br/>";
        // table is property of java.util.Properties which is table of java.util.HashTable.Entry
        tables = toArray(obj.table);

        //Iterate over table and print entries
        for(i = 0;i< tables.length;i++) {
               e = tables[i];
               //Iterate while e is not null
               while(e != null) {
                    if(e.key!= null) {
                        ret +=e.key.toString();
                    }else {
                        ret += 'null';
                    }
                    if(e.value!= null) {
                        ret +=" = "+e.value.toString();
                    }else {
                        ret +=" = null";
                    }
                    ret+="< br/>";
                    e = e.next;
               }
        }
    return ret;
}
// props is static attribute of java.lang.System which holds system Properties.
// pass props to printProp function.
printProp(heap.findClass("java.lang.System").props);

and here is output.

Count = 50
sun.cpu.isalist =
sun.desktop = gnome
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
java.vendor.url.bug = http://java.sun.com/cgi-bin/bugreport.cgi
file.separator = /
java.vendor = Sun Microsystems Inc.
sun.boot.class.path = /usr/java/jdk1.6.0_12/jre/lib/resources.jar:/usr/java/jdk1.6.0_12/jre/lib/rt.jar:/usr/java/jdk1.6.0_12/jre/lib/sunrsasign.jar:/usr/java/jdk1.6.0_12/jre/lib/jsse.jar:/usr/java/jdk1.6.0_12/jre/lib/jce.jar:/usr/java/jdk1.6.0_12/jre/lib/charsets.jar:/usr/java/jdk1.6.0_12/jre/classes
java.ext.dirs = /usr/java/jdk1.6.0_12/jre/lib/ext:/usr/java/packages/lib/ext
java.version = 1.6.0_12-ea
java.vm.info = mixed mode
user.language = en
java.specification.vendor = Sun Microsystems Inc.
java.home = /usr/java/jdk1.6.0_12/jre
sun.arch.data.model = 32
java.vm.specification.version = 1.0
java.class.path = /home/rohand/workspace/java5/bin:
user.name = rohand
file.encoding = UTF-8
java.specification.version = 1.6
java.awt.printerjob = sun.print.PSPrinterJob
user.timezone =
user.home = /home/rohand
os.version = 2.6.33.3-85.fc13.i686.PAE
sun.management.compiler = HotSpot Tiered Compilers
java.specification.name = Java Platform API Specification
java.class.version = 50.0
java.library.path = /usr/java/jdk1.6.0_12/jre/lib/i386/server:/usr/java/jdk1.6.0_12/jre/lib/i386:/usr/java/jdk1.6.0_12/jre/../lib/i386:/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/lib/i386/client:/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/lib/i386:/usr/lib/xulrunner-1.9.2:/usr/lib/xulrunner-1.9.2:/usr/java/packages/lib/i386:/lib:/usr/lib
sun.jnu.encoding = UTF-8
os.name = Linux
java.vm.specification.vendor = Sun Microsystems Inc.
java.io.tmpdir = /tmp
line.separator =

java.endorsed.dirs = /usr/java/jdk1.6.0_12/jre/lib/endorsed
os.arch = i386
java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment
java.runtime.version = 1.6.0_12-ea-b03
java.vm.specification.name = Java Virtual Machine Specification
user.dir = /home/rohand/workspace/java5
sun.java.launcher = SUN_STANDARD
user.country = US
sun.os.patch.level = unknown
java.vm.name = Java HotSpot(TM) Server VM
file.encoding.pkg = sun.io
path.separator = :
java.vm.vendor = Sun Microsystems Inc.
java.vendor.url = http://java.sun.com/
sun.boot.library.path = /usr/java/jdk1.6.0_12/jre/lib/i386
java.vm.version = 11.2-b01
java.runtime.name = Java(TM) SE Runtime Environment

Screenshot of VisualVM OQL Syntax tab

1 comment:

Ernesto Vega said...

Works like a charm.

Thanks a lot !!