1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Copyright (C) 2008 The Android Open Source Project 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * you may not use this file except in compliance with the License. 6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * You may obtain a copy of the License at 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Unless required by applicable law or agreed to in writing, software 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * See the License for the specific language governing permissions and 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * limitations under the License. 15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.Serializable; 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.*; 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/** 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * A loaded class. 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass LoadedClass implements Serializable, Comparable<LoadedClass> { 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static final long serialVersionUID = 0; 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Class name. */ 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final String name; 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Load operations. */ 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final List<Operation> loads = new ArrayList<Operation>(); 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Static initialization operations. */ 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final List<Operation> initializations = new ArrayList<Operation>(); 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Memory usage gathered by loading only this class in its own VM. */ 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MemoryUsage memoryUsage = MemoryUsage.NOT_AVAILABLE; 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Whether or not this class was loaded in the system class loader. 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final boolean systemClass; 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Whether or not this class will be preloaded. */ 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski boolean preloaded; 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Constructs a new class. */ 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LoadedClass(String name, boolean systemClass) { 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.name = name; 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.systemClass = systemClass; 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski void measureMemoryUsage() { 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.memoryUsage = MemoryUsage.forClass(name); 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int mlt = -1; 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Median time to load this class. */ 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int medianLoadTimeMicros() { 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mlt != -1) { 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mlt; 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mlt = calculateMedian(loads); 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int mit = -1; 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Median time to initialize this class. */ 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int medianInitTimeMicros() { 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mit != -1) { 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mit; 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mit = calculateMedian(initializations); 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int medianTimeMicros() { 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return medianInitTimeMicros() + medianLoadTimeMicros(); 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Calculates the median duration for a list of operations. */ 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static int calculateMedian(List<Operation> operations) { 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int size = operations.size(); 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (size == 0) { 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int[] times = new int[size]; 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 0; i < size; i++) { 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski times[i] = operations.get(i).exclusiveTimeMicros(); 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Arrays.sort(times); 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int middle = size / 2; 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (size % 2 == 1) { 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Odd 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return times[middle]; 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Even -- average the two. 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (times[middle - 1] + times[middle]) / 2; 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Returns names of processes that loaded this class. */ 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Set<String> processNames() { 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Set<String> names = new HashSet<String>(); 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addProcessNames(loads, names); 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addProcessNames(initializations, names); 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return names; 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void addProcessNames(List<Operation> ops, Set<String> names) { 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (Operation operation : ops) { 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (operation.process.fromZygote()) { 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski names.add(operation.process.name); 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public int compareTo(LoadedClass o) { 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return name.compareTo(o.name); 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public String toString() { 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return name; 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 131