1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.ahat; 18 19 import com.android.ahat.heapdump.AhatHeap; 20 import com.android.ahat.heapdump.AhatSnapshot; 21 import com.android.ahat.heapdump.Site; 22 import com.android.ahat.heapdump.Sort; 23 import java.io.IOException; 24 import java.util.Collections; 25 import java.util.Comparator; 26 import java.util.List; 27 28 class SiteHandler implements AhatHandler { 29 private static final String ALLOCATION_SITE_ID = "frames"; 30 private static final String SITES_CALLED_ID = "called"; 31 private static final String OBJECTS_ALLOCATED_ID = "objects"; 32 33 private AhatSnapshot mSnapshot; 34 35 public SiteHandler(AhatSnapshot snapshot) { 36 mSnapshot = snapshot; 37 } 38 39 @Override 40 public void handle(Doc doc, Query query) throws IOException { 41 int id = query.getInt("id", 0); 42 int depth = query.getInt("depth", 0); 43 Site site = mSnapshot.getSite(id, depth); 44 45 doc.title("Site"); 46 doc.big(Summarizer.summarize(site)); 47 48 doc.section("Allocation Site"); 49 SitePrinter.printSite(mSnapshot, doc, query, ALLOCATION_SITE_ID, site); 50 51 doc.section("Sites Called from Here"); 52 List<Site> children = site.getChildren(); 53 if (children.isEmpty()) { 54 doc.println(DocString.text("(none)")); 55 } else { 56 Collections.sort(children, Sort.defaultSiteCompare(mSnapshot)); 57 HeapTable.TableConfig<Site> table = new HeapTable.TableConfig<Site>() { 58 public String getHeapsDescription() { 59 return "Reachable Bytes Allocated on Heap"; 60 } 61 62 public long getSize(Site element, AhatHeap heap) { 63 return element.getSize(heap).getSize(); 64 } 65 66 public List<HeapTable.ValueConfig<Site>> getValueConfigs() { 67 HeapTable.ValueConfig<Site> value = new HeapTable.ValueConfig<Site>() { 68 public String getDescription() { 69 return "Child Site"; 70 } 71 72 public DocString render(Site element) { 73 return Summarizer.summarize(element); 74 } 75 }; 76 return Collections.singletonList(value); 77 } 78 }; 79 HeapTable.render(doc, query, SITES_CALLED_ID, table, mSnapshot, children); 80 } 81 82 doc.section("Objects Allocated"); 83 SizeTable.table(doc, mSnapshot.isDiffed(), 84 new Column("Instances", Column.Align.RIGHT), 85 new Column("", Column.Align.RIGHT, mSnapshot.isDiffed()), 86 new Column("Heap"), 87 new Column("Class")); 88 89 List<Site.ObjectsInfo> infos = site.getObjectsInfos(); 90 Comparator<Site.ObjectsInfo> compare = new Sort.WithPriority<Site.ObjectsInfo>( 91 Sort.OBJECTS_INFO_BY_HEAP_NAME, 92 Sort.OBJECTS_INFO_BY_SIZE, 93 Sort.OBJECTS_INFO_BY_CLASS_NAME); 94 Collections.sort(infos, compare); 95 SubsetSelector<Site.ObjectsInfo> selector 96 = new SubsetSelector(query, OBJECTS_ALLOCATED_ID, infos); 97 for (Site.ObjectsInfo info : selector.selected()) { 98 Site.ObjectsInfo baseinfo = info.getBaseline(); 99 String className = info.getClassName(); 100 SizeTable.row(doc, info.numBytes, baseinfo.numBytes, 101 DocString.link( 102 DocString.formattedUri("objects?id=%d&depth=%d&heap=%s&class=%s", 103 site.getId(), site.getDepth(), info.heap.getName(), className), 104 DocString.format("%,14d", info.numInstances)), 105 DocString.delta(false, false, info.numInstances, baseinfo.numInstances), 106 DocString.text(info.heap.getName()), 107 Summarizer.summarize(info.classObj)); 108 } 109 SizeTable.end(doc); 110 selector.render(doc); 111 } 112 } 113 114