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.util.*;
19 
20 /**
21  * A loaded class.
22  */
23 class LoadedClass implements Serializable, Comparable<LoadedClass> {
24 
25     private static final long serialVersionUID = 0;
26 
27     /** Class name. */
28     final String name;
29 
30     /** Load operations. */
31     final List<Operation> loads = new ArrayList<Operation>();
32 
33     /** Static initialization operations. */
34     final List<Operation> initializations = new ArrayList<Operation>();
35 
36     /** Memory usage gathered by loading only this class in its own VM. */
37     MemoryUsage memoryUsage = MemoryUsage.NOT_AVAILABLE;
38 
39     /**
40      * Whether or not this class was loaded in the system class loader.
41      */
42     final boolean systemClass;
43 
44     /** Whether or not this class will be preloaded. */
45     boolean preloaded;
46 
47     /** Constructs a new class. */
LoadedClass(String name, boolean systemClass)48     LoadedClass(String name, boolean systemClass) {
49         this.name = name;
50         this.systemClass = systemClass;
51     }
52 
measureMemoryUsage()53     void measureMemoryUsage() {
54         this.memoryUsage = MemoryUsage.forClass(name);
55     }
56 
57     int mlt = -1;
58 
59     /** Median time to load this class. */
medianLoadTimeMicros()60     int medianLoadTimeMicros() {
61         if (mlt != -1) {
62             return mlt;
63         }
64 
65         return mlt = calculateMedian(loads);
66     }
67 
68     int mit = -1;
69 
70     /** Median time to initialize this class. */
medianInitTimeMicros()71     int medianInitTimeMicros() {
72         if (mit != -1) {
73             return mit;
74         }
75 
76         return mit = calculateMedian(initializations);
77     }
78 
medianTimeMicros()79     int medianTimeMicros() {
80         return medianInitTimeMicros() + medianLoadTimeMicros();
81     }
82 
83     /** Calculates the median duration for a list of operations. */
calculateMedian(List<Operation> operations)84     private static int calculateMedian(List<Operation> operations) {
85         int size = operations.size();
86         if (size == 0) {
87             return 0;
88         }
89 
90         int[] times = new int[size];
91         for (int i = 0; i < size; i++) {
92             times[i] = operations.get(i).exclusiveTimeMicros();
93         }
94 
95         Arrays.sort(times);
96         int middle = size / 2;
97         if (size % 2 == 1) {
98             // Odd
99             return times[middle];
100         } else {
101             // Even -- average the two.
102             return (times[middle - 1] + times[middle]) / 2;
103         }
104     }
105 
106     /** Returns names of processes that loaded this class. */
processNames()107     Set<String> processNames() {
108         Set<String> names = new HashSet<String>();
109         addProcessNames(loads, names);
110         addProcessNames(initializations, names);
111         return names;
112     }
113 
addProcessNames(List<Operation> ops, Set<String> names)114     private void addProcessNames(List<Operation> ops, Set<String> names) {
115         for (Operation operation : ops) {
116             if (operation.process.fromZygote()) {
117                 names.add(operation.process.name);
118             }
119         }
120     }
121 
compareTo(LoadedClass o)122     public int compareTo(LoadedClass o) {
123         return name.compareTo(o.name);
124     }
125 
126     @Override
toString()127     public String toString() {
128         return name;
129     }
130 }
131