19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.Serializable; 182e93f65cab0b4b21a1285b83e985559325e87a3aBob Leeimport java.util.*; 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A loaded class. 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass LoadedClass implements Serializable, Comparable<LoadedClass> { 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final long serialVersionUID = 0; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Class name. */ 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String name; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Load operations. */ 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final List<Operation> loads = new ArrayList<Operation>(); 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Static initialization operations. */ 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final List<Operation> initializations = new ArrayList<Operation>(); 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Memory usage gathered by loading only this class in its own VM. */ 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MemoryUsage memoryUsage = MemoryUsage.NOT_AVAILABLE; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Whether or not this class was loaded in the system class loader. 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean systemClass; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Whether or not this class will be preloaded. */ 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean preloaded; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Constructs a new class. */ 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LoadedClass(String name, boolean systemClass) { 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.name = name; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.systemClass = systemClass; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void measureMemoryUsage() { 549d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee this.memoryUsage = MemoryUsage.forClass(name); 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mlt = -1; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Median time to load this class. */ 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int medianLoadTimeMicros() { 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mlt != -1) { 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mlt; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mlt = calculateMedian(loads); 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mit = -1; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Median time to initialize this class. */ 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int medianInitTimeMicros() { 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mit != -1) { 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mit; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mit = calculateMedian(initializations); 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 799d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee int medianTimeMicros() { 809d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return medianInitTimeMicros() + medianLoadTimeMicros(); 819d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 829d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Calculates the median duration for a list of operations. */ 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static int calculateMedian(List<Operation> operations) { 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = operations.size(); 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (size == 0) { 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] times = new int[size]; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project times[i] = operations.get(i).exclusiveTimeMicros(); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Arrays.sort(times); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int middle = size / 2; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (size % 2 == 1) { 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Odd 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return times[middle]; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Even -- average the two. 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (times[middle - 1] + times[middle]) / 2; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1069d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee /** Returns names of processes that loaded this class. */ 1079d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Set<String> processNames() { 1089d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Set<String> names = new HashSet<String>(); 1099d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee addProcessNames(loads, names); 1109d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee addProcessNames(initializations, names); 1119d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return names; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1149d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee private void addProcessNames(List<Operation> ops, Set<String> names) { 1152e93f65cab0b4b21a1285b83e985559325e87a3aBob Lee for (Operation operation : ops) { 1169d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (operation.process.fromZygote()) { 1179d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee names.add(operation.process.name); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int compareTo(LoadedClass o) { 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return name.compareTo(o.name); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return name; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 131