2 * Copyright (C) 2008 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
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;
29 import java.util.HashMap;
31 import java.util.TreeSet;
32 import java.util.Arrays;
33 import java.nio.charset.Charset;
36 * Root of our data model.
38 public class Root implements Serializable {
40 private static final long serialVersionUID = 0;
43 final Map<Integer, Proc> processes = new HashMap<Integer, Proc>();
45 /** Class name -> LoadedClass */
46 final Map<String, LoadedClass> loadedClasses
47 = new HashMap<String, LoadedClass>();
49 MemoryUsage baseline = MemoryUsage.baseline();
52 * Records class loads and initializations.
54 void indexClassOperation(Record record) {
55 Proc process = processes.get(record.pid);
57 // Ignore dexopt output. It loads applications classes through the
58 // system class loader and messes us up.
59 if (record.processName.equals("dexopt")) {
63 String name = record.className;
64 LoadedClass loadedClass = loadedClasses.get(name);
67 switch (record.type) {
70 if (loadedClass == null) {
71 loadedClass = new LoadedClass(
72 name, record.classLoader == 0);
73 if (loadedClass.systemClass) {
74 // Only measure memory for classes in the boot
76 loadedClass.measureMemoryUsage();
78 loadedClasses.put(name, loadedClass);
84 o = process.endOperation(record.tid, record.className,
85 loadedClass, record.time);
91 switch (record.type) {
93 process.startOperation(record.tid, loadedClass, record.time,
98 process.startOperation(record.tid, loadedClass, record.time,
103 loadedClass.loads.add(o);
107 loadedClass.initializations.add(o);
113 * Indexes information about the process from the given record.
115 void indexProcess(Record record) {
116 Proc proc = processes.get(record.pid);
119 // Create a new process object.
120 Proc parent = processes.get(record.ppid);
121 proc = new Proc(parent, record.pid);
122 processes.put(proc.id, proc);
123 if (parent != null) {
124 parent.children.add(proc);
128 proc.setName(record.processName);
132 * Writes this graph to a file.
134 void toFile(String fileName) throws IOException {
135 FileOutputStream out = new FileOutputStream(fileName);
136 ObjectOutputStream oout = new ObjectOutputStream(
137 new BufferedOutputStream(out));
139 System.err.println("Writing object model...");
141 oout.writeObject(this);
145 System.err.println("Done!");
149 * Reads Root from a file.
151 static Root fromFile(String fileName)
152 throws IOException, ClassNotFoundException {
153 FileInputStream fin = new FileInputStream(fileName);
154 ObjectInputStream oin = new ObjectInputStream(
155 new BufferedInputStream(fin));
157 Root root = (Root) oin.readObject();