• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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