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