From 1af86f17dc9a47faf1c6cd7ccd23d248fdc615ab Mon Sep 17 00:00:00 2001 From: Richard Uhler Date: Thu, 29 Oct 2015 14:55:00 -0700 Subject: ahat: limit default number of results shown. Previously, ahat had performance issues rendering large pages. This change causes ahat to limit the number results shown in large pages by default, requiring the user to explicitly request more information if they care about it. Bug: 25114227 Change-Id: Ief67396be254be4c84e6971f5b903a701206e17b --- tools/ahat/src/ObjectHandler.java | 81 +++++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 25 deletions(-) (limited to 'tools/ahat/src/ObjectHandler.java') diff --git a/tools/ahat/src/ObjectHandler.java b/tools/ahat/src/ObjectHandler.java index 5e321e267e..9e4ce563d5 100644 --- a/tools/ahat/src/ObjectHandler.java +++ b/tools/ahat/src/ObjectHandler.java @@ -25,13 +25,26 @@ import com.android.tools.perflib.heap.Instance; import com.android.tools.perflib.heap.RootObj; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; -class ObjectHandler extends AhatHandler { +class ObjectHandler implements AhatHandler { + + private static final String ARRAY_ELEMENTS_ID = "elements"; + private static final String DOMINATOR_PATH_ID = "dompath"; + private static final String ALLOCATION_SITE_ID = "frames"; + private static final String DOMINATED_OBJECTS_ID = "dominated"; + private static final String INSTANCE_FIELDS_ID = "ifields"; + private static final String STATIC_FIELDS_ID = "sfields"; + private static final String HARD_REFS_ID = "refs"; + private static final String SOFT_REFS_ID = "srefs"; + + private AhatSnapshot mSnapshot; + public ObjectHandler(AhatSnapshot snapshot) { - super(snapshot); + mSnapshot = snapshot; } @Override @@ -46,8 +59,8 @@ class ObjectHandler extends AhatHandler { doc.title("Object %08x", inst.getUniqueId()); doc.big(Value.render(inst)); - printAllocationSite(doc, inst); - printDominatorPath(doc, inst); + printAllocationSite(doc, query, inst); + printDominatorPath(doc, query, inst); doc.section("Object Info"); ClassObj cls = inst.getClassObj(); @@ -62,39 +75,46 @@ class ObjectHandler extends AhatHandler { printBitmap(doc, inst); if (inst instanceof ClassInstance) { - printClassInstanceFields(doc, (ClassInstance)inst); + printClassInstanceFields(doc, query, (ClassInstance)inst); } else if (inst instanceof ArrayInstance) { - printArrayElements(doc, (ArrayInstance)inst); + printArrayElements(doc, query, (ArrayInstance)inst); } else if (inst instanceof ClassObj) { - printClassInfo(doc, (ClassObj)inst); + printClassInfo(doc, query, (ClassObj)inst); } - printReferences(doc, inst); + printReferences(doc, query, inst); printDominatedObjects(doc, query, inst); } - private static void printClassInstanceFields(Doc doc, ClassInstance inst) { + private static void printClassInstanceFields(Doc doc, Query query, ClassInstance inst) { doc.section("Fields"); doc.table(new Column("Type"), new Column("Name"), new Column("Value")); - for (ClassInstance.FieldValue field : inst.getValues()) { + SubsetSelector selector + = new SubsetSelector(query, INSTANCE_FIELDS_ID, inst.getValues()); + for (ClassInstance.FieldValue field : selector.selected()) { doc.row( DocString.text(field.getField().getType().toString()), DocString.text(field.getField().getName()), Value.render(field.getValue())); } doc.end(); + selector.render(doc); } - private static void printArrayElements(Doc doc, ArrayInstance array) { + private static void printArrayElements(Doc doc, Query query, ArrayInstance array) { doc.section("Array Elements"); doc.table(new Column("Index", Column.Align.RIGHT), new Column("Value")); - Object[] elements = array.getValues(); - for (int i = 0; i < elements.length; i++) { - doc.row(DocString.format("%d", i), Value.render(elements[i])); + List elements = Arrays.asList(array.getValues()); + SubsetSelector selector = new SubsetSelector(query, ARRAY_ELEMENTS_ID, elements); + int i = 0; + for (Object elem : selector.selected()) { + doc.row(DocString.format("%d", i), Value.render(elem)); + i++; } doc.end(); + selector.render(doc); } - private static void printClassInfo(Doc doc, ClassObj clsobj) { + private static void printClassInfo(Doc doc, Query query, ClassObj clsobj) { doc.section("Class Info"); doc.descriptions(); doc.description(DocString.text("Super Class"), Value.render(clsobj.getSuperClassObj())); @@ -103,41 +123,52 @@ class ObjectHandler extends AhatHandler { doc.section("Static Fields"); doc.table(new Column("Type"), new Column("Name"), new Column("Value")); - for (Map.Entry field : clsobj.getStaticFieldValues().entrySet()) { + List> fields + = new ArrayList>(clsobj.getStaticFieldValues().entrySet()); + SubsetSelector> selector + = new SubsetSelector(query, STATIC_FIELDS_ID, fields); + for (Map.Entry field : selector.selected()) { doc.row( DocString.text(field.getKey().getType().toString()), DocString.text(field.getKey().getName()), Value.render(field.getValue())); } doc.end(); + selector.render(doc); } - private static void printReferences(Doc doc, Instance inst) { + private static void printReferences(Doc doc, Query query, Instance inst) { doc.section("Objects with References to this Object"); if (inst.getHardReferences().isEmpty()) { doc.println(DocString.text("(none)")); } else { doc.table(new Column("Object")); - for (Instance ref : inst.getHardReferences()) { + List references = inst.getHardReferences(); + SubsetSelector selector = new SubsetSelector(query, HARD_REFS_ID, references); + for (Instance ref : selector.selected()) { doc.row(Value.render(ref)); } doc.end(); + selector.render(doc); } if (inst.getSoftReferences() != null) { doc.section("Objects with Soft References to this Object"); doc.table(new Column("Object")); - for (Instance ref : inst.getSoftReferences()) { - doc.row(Value.render(inst)); + List references = inst.getSoftReferences(); + SubsetSelector selector = new SubsetSelector(query, SOFT_REFS_ID, references); + for (Instance ref : selector.selected()) { + doc.row(Value.render(ref)); } doc.end(); + selector.render(doc); } } - private void printAllocationSite(Doc doc, Instance inst) { + private void printAllocationSite(Doc doc, Query query, Instance inst) { doc.section("Allocation Site"); Site site = mSnapshot.getSiteForInstance(inst); - SitePrinter.printSite(doc, mSnapshot, site); + SitePrinter.printSite(mSnapshot, doc, query, ALLOCATION_SITE_ID, site); } // Draw the bitmap corresponding to this instance if there is one. @@ -150,7 +181,7 @@ class ObjectHandler extends AhatHandler { } } - private void printDominatorPath(Doc doc, Instance inst) { + private void printDominatorPath(Doc doc, Query query, Instance inst) { doc.section("Dominator Path from Root"); List path = new ArrayList(); for (Instance parent = inst; @@ -193,14 +224,14 @@ class ObjectHandler extends AhatHandler { return Collections.singletonList(value); } }; - HeapTable.render(doc, table, mSnapshot, path); + HeapTable.render(doc, query, DOMINATOR_PATH_ID, table, mSnapshot, path); } public void printDominatedObjects(Doc doc, Query query, Instance inst) { doc.section("Immediately Dominated Objects"); List instances = mSnapshot.getDominated(inst); if (instances != null) { - DominatedList.render(mSnapshot, doc, instances, query); + DominatedList.render(mSnapshot, doc, query, DOMINATED_OBJECTS_ID, instances); } else { doc.println(DocString.text("(none)")); } -- cgit v1.2.3-59-g8ed1b