1 /* 2 * Copyright (C) 2008 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 import java.io.Serializable; 18 import java.io.IOException; 19 import java.io.Writer; 20 import java.io.BufferedWriter; 21 import java.io.OutputStreamWriter; 22 import java.io.FileOutputStream; 23 import java.io.FileInputStream; 24 import java.io.ObjectInputStream; 25 import java.io.BufferedInputStream; 26 import java.io.ObjectOutputStream; 27 import java.io.BufferedOutputStream; 28 import java.util.Map; 29 import java.util.HashMap; 30 import java.util.Set; 31 import java.util.TreeSet; 32 import java.util.Arrays; 33 import java.nio.charset.Charset; 34 35 /** 36 * Root of our data model. 37 */ 38 public class Root implements Serializable { 39 40 private static final long serialVersionUID = 0; 41 42 /** pid -> Proc */ 43 final Map<Integer, Proc> processes = new HashMap<Integer, Proc>(); 44 45 /** Class name -> LoadedClass */ 46 final Map<String, LoadedClass> loadedClasses 47 = new HashMap<String, LoadedClass>(); 48 49 // MemoryUsage baseline = MemoryUsage.baseline(); 50 MemoryUsage baseline = MemoryUsage.NOT_AVAILABLE; 51 52 /** 53 * Records class loads and initializations. 54 */ indexClassOperation(Record record)55 void indexClassOperation(Record record) { 56 Proc process = processes.get(record.pid); 57 58 // Ignore dexopt output. It loads applications classes through the 59 // system class loader and messes us up. 60 if (record.processName.equals("dexopt")) { 61 return; 62 } 63 64 String name = record.className; 65 LoadedClass loadedClass = loadedClasses.get(name); 66 Operation o = null; 67 68 switch (record.type) { 69 case START_LOAD: 70 case START_INIT: 71 if (loadedClass == null) { 72 loadedClass = new LoadedClass( 73 name, record.classLoader == 0); 74 if (loadedClass.systemClass) { 75 // Only measure memory for classes in the boot 76 // classpath. 77 // loadedClass.measureMemoryUsage(); 78 } 79 loadedClasses.put(name, loadedClass); 80 } 81 break; 82 83 case END_LOAD: 84 case END_INIT: 85 o = process.endOperation(record.tid, record.className, 86 loadedClass, record.time); 87 if (o == null) { 88 return; 89 } 90 } 91 92 switch (record.type) { 93 case START_LOAD: 94 process.startOperation(record.tid, loadedClass, record.time, 95 Operation.Type.LOAD); 96 break; 97 98 case START_INIT: 99 process.startOperation(record.tid, loadedClass, record.time, 100 Operation.Type.INIT); 101 break; 102 103 case END_LOAD: 104 loadedClass.loads.add(o); 105 break; 106 107 case END_INIT: 108 loadedClass.initializations.add(o); 109 break; 110 } 111 } 112 113 /** 114 * Indexes information about the process from the given record. 115 */ indexProcess(Record record)116 void indexProcess(Record record) { 117 Proc proc = processes.get(record.pid); 118 119 if (proc == null) { 120 // Create a new process object. 121 Proc parent = processes.get(record.ppid); 122 proc = new Proc(parent, record.pid); 123 processes.put(proc.id, proc); 124 if (parent != null) { 125 parent.children.add(proc); 126 } 127 } 128 129 proc.setName(record.processName); 130 } 131 132 /** 133 * Writes this graph to a file. 134 */ toFile(String fileName)135 void toFile(String fileName) throws IOException { 136 FileOutputStream out = new FileOutputStream(fileName); 137 ObjectOutputStream oout = new ObjectOutputStream( 138 new BufferedOutputStream(out)); 139 140 System.err.println("Writing object model..."); 141 142 oout.writeObject(this); 143 144 oout.close(); 145 146 System.err.println("Done!"); 147 } 148 149 /** 150 * Reads Root from a file. 151 */ fromFile(String fileName)152 static Root fromFile(String fileName) 153 throws IOException, ClassNotFoundException { 154 FileInputStream fin = new FileInputStream(fileName); 155 ObjectInputStream oin = new ObjectInputStream( 156 new BufferedInputStream(fin)); 157 158 Root root = (Root) oin.readObject(); 159 160 oin.close(); 161 162 return root; 163 } 164 } 165