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.ArrayList; 25 import java.util.Collections; 26 import java.util.Comparator; 27 import java.util.List; 28 29 class SiteHandler implements AhatHandler { 30 private static final String ALLOCATION_SITE_ID = "frames"; 31 private static final String SITES_CALLED_ID = "called"; 32 private static final String OBJECTS_ALLOCATED_ID = "objects"; 33 34 private AhatSnapshot mSnapshot; 35 SiteHandler(AhatSnapshot snapshot)36 public SiteHandler(AhatSnapshot snapshot) { 37 mSnapshot = snapshot; 38 } 39 40 @Override handle(Doc doc, Query query)41 public void handle(Doc doc, Query query) throws IOException { 42 int id = query.getInt("id", 0); 43 Site site = mSnapshot.getSite(id); 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 = new ArrayList<Site>(site.getChildren()); 53 54 if (children.isEmpty()) { 55 doc.println(DocString.text("(none)")); 56 } else { 57 Collections.sort(children, Sort.defaultSiteCompare(mSnapshot)); 58 HeapTable.TableConfig<Site> table = new HeapTable.TableConfig<Site>() { 59 public String getHeapsDescription() { 60 return "Reachable Bytes Allocated on Heap"; 61 } 62 63 public long getSize(Site element, AhatHeap heap) { 64 return element.getSize(heap).getSize(); 65 } 66 67 public List<HeapTable.ValueConfig<Site>> getValueConfigs() { 68 HeapTable.ValueConfig<Site> value = new HeapTable.ValueConfig<Site>() { 69 public String getDescription() { 70 return "Child Site"; 71 } 72 73 public DocString render(Site element) { 74 return Summarizer.summarize(element); 75 } 76 }; 77 return Collections.singletonList(value); 78 } 79 }; 80 HeapTable.render(doc, query, SITES_CALLED_ID, table, mSnapshot, children); 81 } 82 83 doc.section("Objects Allocated"); 84 SizeTable.table(doc, mSnapshot.isDiffed(), 85 new Column("Instances", Column.Align.RIGHT), 86 new Column("Δ", Column.Align.RIGHT, mSnapshot.isDiffed()), 87 new Column("Heap"), 88 new Column("Class")); 89 90 List<Site.ObjectsInfo> infos = site.getObjectsInfos(); 91 Comparator<Site.ObjectsInfo> compare = Sort.withPriority( 92 Sort.OBJECTS_INFO_BY_HEAP_NAME, 93 Sort.OBJECTS_INFO_BY_SIZE, 94 Sort.OBJECTS_INFO_BY_CLASS_NAME); 95 Collections.sort(infos, compare); 96 SubsetSelector<Site.ObjectsInfo> selector 97 = new SubsetSelector(query, OBJECTS_ALLOCATED_ID, infos); 98 for (Site.ObjectsInfo info : selector.selected()) { 99 Site.ObjectsInfo baseinfo = info.getBaseline(); 100 String className = info.getClassName(); 101 SizeTable.row(doc, info.numBytes, baseinfo.numBytes, 102 DocString.link( 103 DocString.formattedUri("objects?id=%d&heap=%s&class=%s", 104 site.getId(), info.heap.getName(), className), 105 DocString.format("%,14d", info.numInstances)), 106 DocString.delta(false, false, info.numInstances, baseinfo.numInstances), 107 DocString.text(info.heap.getName()), 108 Summarizer.summarize(info.classObj)); 109 } 110 SizeTable.end(doc); 111 selector.render(doc); 112 } 113 } 114 115