blob: 0bc29bfdd937e8d95895d4de20a4db88c91f8cf2 [file] [log] [blame]
Adam Lesinski282e1812014-01-23 18:17:42 -08001/*
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
17import java.io.Serializable;
18import java.io.IOException;
19import java.io.Writer;
20import java.io.BufferedWriter;
21import java.io.OutputStreamWriter;
22import java.io.FileOutputStream;
23import java.io.FileInputStream;
24import java.io.ObjectInputStream;
25import java.io.BufferedInputStream;
26import java.io.ObjectOutputStream;
27import java.io.BufferedOutputStream;
28import java.util.Map;
29import java.util.HashMap;
30import java.util.Set;
31import java.util.TreeSet;
32import java.util.Arrays;
33import java.nio.charset.Charset;
34
35/**
36 * Root of our data model.
37 */
38public 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
51 /**
52 * Records class loads and initializations.
53 */
54 void indexClassOperation(Record record) {
55 Proc process = processes.get(record.pid);
56
57 // Ignore dexopt output. It loads applications classes through the
58 // system class loader and messes us up.
59 if (record.processName.equals("dexopt")) {
60 return;
61 }
62
63 String name = record.className;
64 LoadedClass loadedClass = loadedClasses.get(name);
65 Operation o = null;
66
67 switch (record.type) {
68 case START_LOAD:
69 case START_INIT:
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
75 // classpath.
76 loadedClass.measureMemoryUsage();
77 }
78 loadedClasses.put(name, loadedClass);
79 }
80 break;
81
82 case END_LOAD:
83 case END_INIT:
84 o = process.endOperation(record.tid, record.className,
85 loadedClass, record.time);
86 if (o == null) {
87 return;
88 }
89 }
90
91 switch (record.type) {
92 case START_LOAD:
93 process.startOperation(record.tid, loadedClass, record.time,
94 Operation.Type.LOAD);
95 break;
96
97 case START_INIT:
98 process.startOperation(record.tid, loadedClass, record.time,
99 Operation.Type.INIT);
100 break;
101
102 case END_LOAD:
103 loadedClass.loads.add(o);
104 break;
105
106 case END_INIT:
107 loadedClass.initializations.add(o);
108 break;
109 }
110 }
111
112 /**
113 * Indexes information about the process from the given record.
114 */
115 void indexProcess(Record record) {
116 Proc proc = processes.get(record.pid);
117
118 if (proc == null) {
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);
125 }
126 }
127
128 proc.setName(record.processName);
129 }
130
131 /**
132 * Writes this graph to a file.
133 */
134 void toFile(String fileName) throws IOException {
135 FileOutputStream out = new FileOutputStream(fileName);
136 ObjectOutputStream oout = new ObjectOutputStream(
137 new BufferedOutputStream(out));
138
139 System.err.println("Writing object model...");
140
141 oout.writeObject(this);
142
143 oout.close();
144
145 System.err.println("Done!");
146 }
147
148 /**
149 * Reads Root from a file.
150 */
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));
156
157 Root root = (Root) oin.readObject();
158
159 oin.close();
160
161 return root;
162 }
163}