Mercurial > hg > graal-compiler
diff agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java @ 0:a61af66fc99e jdk7-b24
Initial load
author | duke |
---|---|
date | Sat, 01 Dec 2007 00:00:00 +0000 |
parents | |
children | c18cbe5936b8 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java Sat Dec 01 00:00:00 2007 +0000 @@ -0,0 +1,138 @@ +/* + * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package sun.jvm.hotspot.tools; + +import sun.jvm.hotspot.tools.*; + +import sun.jvm.hotspot.oops.*; +import sun.jvm.hotspot.runtime.VM; +import sun.jvm.hotspot.utilities.SystemDictionaryHelper; +import sun.jvm.hotspot.utilities.ObjectReader; +import sun.jvm.hotspot.utilities.MarkBits; + +import java.util.HashMap; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; + +/* + * Iterates over the queue of object pending finalization and prints a + * summary of these objects in the form of a histogram. + */ +public class FinalizerInfo extends Tool { + public static void main(String[] args) { + FinalizerInfo finfo = new FinalizerInfo(); + finfo.start(args); + finfo.stop(); + } + + public void run() { + /* + * The implementation here has a dependency on the implementation of + * java.lang.ref.Finalizer. If the Finalizer implementation changes it's + * possible this method will require changes too. We looked into using + * ObjectReader to deserialize the objects from the target VM but as + * there aren't any public methods to traverse the queue it means using + * reflection which will also tie us to the implementation. + * + * The assumption here is that Finalizer.queue is the ReferenceQueue + * with the objects awaiting finalization. The ReferenceQueue queueLength + * is the number of objects in the queue, and 'head' is the head of the + * queue. + */ + InstanceKlass ik = + SystemDictionaryHelper.findInstanceKlass("java.lang.ref.Finalizer"); + final OopField queueField[] = new OopField[1]; + ik.iterateFields(new DefaultOopVisitor() { + public void doOop(OopField field, boolean isVMField) { + String name = field.getID().getName(); + if (name.equals("queue")) { + queueField[0] = field; + } + } + }, false); + Oop queue = queueField[0].getValue(ik); + + InstanceKlass k = (InstanceKlass) queue.getKlass(); + + LongField queueLengthField = (LongField) k.findField("queueLength", "J"); + long queueLength = queueLengthField.getValue(queue); + + OopField headField = (OopField) k.findField("head", "Ljava/lang/ref/Reference;"); + Oop head = headField.getValue(queue); + + System.out.println("Number of objects pending for finalization: " + queueLength); + + /* + * If 'head' is non-NULL then it is the head of a list of References. + * We iterate over the list (end of list is when head.next == head) + */ + if (head != null) { + k = (InstanceKlass) head.getKlass(); + OopField referentField = + (OopField) k.findField("referent", "Ljava/lang/Object;"); + OopField nextField = + (OopField) k.findField("next", "Ljava/lang/ref/Reference;"); + + HashMap map = new HashMap(); + for (;;) { + Oop referent = referentField.getValue(head); + + Klass klass = referent.getKlass(); + if (!map.containsKey(klass)) { + map.put(klass, new ObjectHistogramElement(klass)); + } + ((ObjectHistogramElement)map.get(klass)).updateWith(referent); + + Oop next = nextField.getValue(head); + if (next == null || next.equals(head)) break; + head = next; + } + + /* + * Sort results - decending order by total size + */ + ArrayList list = new ArrayList(); + list.addAll(map.values()); + Collections.sort(list, new Comparator() { + public int compare(Object o1, Object o2) { + return ((ObjectHistogramElement)o1).compare((ObjectHistogramElement)o2); + } + }); + + /* + * Print summary of objects in queue + */ + System.out.println(""); + System.out.println("Count" + "\t" + "Class description"); + System.out.println("-------------------------------------------------------"); + for (int i=0; i<list.size(); i++) { + ObjectHistogramElement e = (ObjectHistogramElement)list.get(i); + System.out.println(e.getCount() + "\t" + e.getDescription()); + } + } + + } +}