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 17package com.android.ahat; 18 19import com.android.ahat.heapdump.AhatHeap; 20import com.android.ahat.heapdump.AhatSnapshot; 21import com.android.ahat.heapdump.Site; 22import com.android.ahat.heapdump.Sort; 23import java.io.IOException; 24import java.util.Collections; 25import java.util.Comparator; 26import java.util.List; 27 28class 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); 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 84 doc.table( 85 new Column("Reachable Bytes Allocated", Column.Align.RIGHT), 86 new Column("Δ", Column.Align.RIGHT, mSnapshot.isDiffed()), 87 new Column("Instances", Column.Align.RIGHT), 88 new Column("Δ", Column.Align.RIGHT, mSnapshot.isDiffed()), 89 new Column("Heap"), 90 new Column("Class")); 91 92 List<Site.ObjectsInfo> infos = site.getObjectsInfos(); 93 Comparator<Site.ObjectsInfo> compare = new Sort.WithPriority<Site.ObjectsInfo>( 94 Sort.OBJECTS_INFO_BY_HEAP_NAME, 95 Sort.OBJECTS_INFO_BY_SIZE, 96 Sort.OBJECTS_INFO_BY_CLASS_NAME); 97 Collections.sort(infos, compare); 98 SubsetSelector<Site.ObjectsInfo> selector 99 = new SubsetSelector(query, OBJECTS_ALLOCATED_ID, infos); 100 for (Site.ObjectsInfo info : selector.selected()) { 101 Site.ObjectsInfo baseinfo = info.getBaseline(); 102 String className = info.getClassName(); 103 doc.row( 104 DocString.format("%,14d", info.numBytes), 105 DocString.delta(false, false, info.numBytes, baseinfo.numBytes), 106 DocString.link( 107 DocString.formattedUri("objects?id=%d&depth=%d&heap=%s&class=%s", 108 site.getId(), site.getDepth(), info.heap.getName(), className), 109 DocString.format("%,14d", info.numInstances)), 110 DocString.delta(false, false, info.numInstances, baseinfo.numInstances), 111 DocString.text(info.heap.getName()), 112 Summarizer.summarize(info.classObj)); 113 } 114 doc.end(); 115 selector.render(doc); 116 } 117} 118 119