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; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.BufferedReader; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStreamReader; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.OutputStream; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Arrays; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Memory usage information. 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass MemoryUsage implements Serializable { 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final long serialVersionUID = 0; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final MemoryUsage NOT_AVAILABLE = new MemoryUsage(); 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static int errorCount = 0; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee // These values are in 1kB increments (not 4kB like you'd expect). 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int nativeSharedPages; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int javaSharedPages; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int otherSharedPages; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int nativePrivatePages; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int javaPrivatePages; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int otherPrivatePages; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int allocCount; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int allocSize; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int freedCount; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int freedSize; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long nativeHeapSize; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public MemoryUsage(String line) { 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] parsed = line.split(","); 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nativeSharedPages = Integer.parseInt(parsed[1]); 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project javaSharedPages = Integer.parseInt(parsed[2]); 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project otherSharedPages = Integer.parseInt(parsed[3]); 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nativePrivatePages = Integer.parseInt(parsed[4]); 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project javaPrivatePages = Integer.parseInt(parsed[5]); 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project otherPrivatePages = Integer.parseInt(parsed[6]); 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project allocCount = Integer.parseInt(parsed[7]); 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project allocSize = Integer.parseInt(parsed[8]); 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project freedCount = Integer.parseInt(parsed[9]); 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project freedSize = Integer.parseInt(parsed[10]); 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nativeHeapSize = Long.parseLong(parsed[11]); 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MemoryUsage() { 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nativeSharedPages = -1; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project javaSharedPages = -1; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project otherSharedPages = -1; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nativePrivatePages = -1; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project javaPrivatePages = -1; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project otherPrivatePages = -1; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project allocCount = -1; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project allocSize = -1; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project freedCount = -1; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project freedSize = -1; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nativeHeapSize = -1; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MemoryUsage(int nativeSharedPages, 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int javaSharedPages, 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int otherSharedPages, 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nativePrivatePages, 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int javaPrivatePages, 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int otherPrivatePages, 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int allocCount, 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int allocSize, 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int freedCount, 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int freedSize, 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long nativeHeapSize) { 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.nativeSharedPages = nativeSharedPages; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.javaSharedPages = javaSharedPages; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.otherSharedPages = otherSharedPages; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.nativePrivatePages = nativePrivatePages; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.javaPrivatePages = javaPrivatePages; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.otherPrivatePages = otherPrivatePages; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.allocCount = allocCount; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.allocSize = allocSize; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.freedCount = freedCount; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.freedSize = freedSize; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.nativeHeapSize = nativeHeapSize; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MemoryUsage subtract(MemoryUsage baseline) { 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new MemoryUsage( 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nativeSharedPages - baseline.nativeSharedPages, 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project javaSharedPages - baseline.javaSharedPages, 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project otherSharedPages - baseline.otherSharedPages, 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nativePrivatePages - baseline.nativePrivatePages, 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project javaPrivatePages - baseline.javaPrivatePages, 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project otherPrivatePages - baseline.otherPrivatePages, 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project allocCount - baseline.allocCount, 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project allocSize - baseline.allocSize, 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project freedCount - baseline.freedCount, 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project freedSize - baseline.freedSize, 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nativeHeapSize - baseline.nativeHeapSize); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int javaHeapSize() { 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return allocSize - freedSize; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1269d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee int totalHeap() { 1279d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return javaHeapSize() + (int) nativeHeapSize; 1289d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1299d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int javaPagesInK() { 1319d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return javaSharedPages + javaPrivatePages; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nativePagesInK() { 1359d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return nativeSharedPages + nativePrivatePages; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int otherPagesInK() { 1389d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return otherSharedPages + otherPrivatePages; 1399d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 1409d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 1419d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee int totalPages() { 1429d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee return javaSharedPages + javaPrivatePages + nativeSharedPages + 1439d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee nativePrivatePages + otherSharedPages + otherPrivatePages; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Was this information available? 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isAvailable() { 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return nativeSharedPages != -1; 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Measures baseline memory usage. 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static MemoryUsage baseline() { 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return forClass(null); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String CLASS_PATH = "-Xbootclasspath" 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ":/system/framework/core.jar" 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ":/system/framework/ext.jar" 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ":/system/framework/framework.jar" 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ":/system/framework/framework-tests.jar" 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ":/system/framework/services.jar" 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ":/system/framework/loadclass.jar"; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String[] GET_DIRTY_PAGES = { 169e9fcaa0697dcb257d0288118347f721ce8806b55Jesse Wilson "adb", "shell", "dalvikvm", CLASS_PATH, "LoadClass" }; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Measures memory usage for the given class. 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static MemoryUsage forClass(String className) { 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MeasureWithTimeout measurer = new MeasureWithTimeout(className); 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new Thread(measurer).start(); 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (measurer) { 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (measurer.memoryUsage == null) { 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Wait up to 10s. 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project measurer.wait(30000); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.err.println("Interrupted waiting for measurement."); 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e.printStackTrace(); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NOT_AVAILABLE; 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If it's still null. 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (measurer.memoryUsage == null) { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.err.println("Timed out while measuring " 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + className + "."); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NOT_AVAILABLE; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.err.println("Got memory usage for " + className + "."); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return measurer.memoryUsage; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static class MeasureWithTimeout implements Runnable { 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String className; 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MemoryUsage memoryUsage = null; 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MeasureWithTimeout(String className) { 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.className = className; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MemoryUsage measured = measure(); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memoryUsage = measured; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyAll(); 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private MemoryUsage measure() { 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] commands = GET_DIRTY_PAGES; 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (className != null) { 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<String> commandList = new ArrayList<String>( 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GET_DIRTY_PAGES.length + 1); 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project commandList.addAll(Arrays.asList(commands)); 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project commandList.add(className); 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project commands = commandList.toArray(new String[commandList.size()]); 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Process process = Runtime.getRuntime().exec(commands); 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final InputStream err = process.getErrorStream(); 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Send error output to stderr. 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Thread errThread = new Thread() { 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project copy(err, System.err); 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project errThread.setDaemon(true); 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project errThread.start(); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BufferedReader in = new BufferedReader( 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new InputStreamReader(process.getInputStream())); 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String line = in.readLine(); 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (line == null || !line.startsWith("DECAFBAD,")) { 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.err.println("Got bad response for " + className 251e9fcaa0697dcb257d0288118347f721ce8806b55Jesse Wilson + ": " + line + "; command was " + Arrays.toString(commands)); 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project errorCount += 1; 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NOT_AVAILABLE; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project in.close(); 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project err.close(); 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project process.destroy(); 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new MemoryUsage(line); 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.err.println("Error getting stats for " 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + className + "."); 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e.printStackTrace(); 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NOT_AVAILABLE; 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copies from one stream to another. 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static void copy(InputStream in, OutputStream out) { 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] buffer = new byte[1024]; 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int read; 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((read = in.read(buffer)) > -1) { 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.write(buffer, 0, read); 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e.printStackTrace(); 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2859d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee 2869d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee /** Measures memory usage information and stores it in the model. */ 2879d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee public static void main(String[] args) throws IOException, 2889d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee ClassNotFoundException { 2899d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee Root root = Root.fromFile(args[0]); 2909d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee root.baseline = baseline(); 2919d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee for (LoadedClass loadedClass : root.loadedClasses.values()) { 2929d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee if (loadedClass.systemClass) { 2939d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee loadedClass.measureMemoryUsage(); 2949d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 2959d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 2969d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee root.toFile(args[0]); 2979d2d6e14b0932b6a74e01f393d5efed61458941bBob Lee } 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 299