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.io.IOException; 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.BufferedReader; 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.InputStreamReader; 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.InputStream; 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.OutputStream; 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.List; 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.ArrayList; 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.Arrays; 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/** 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Memory usage information. 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass MemoryUsage implements Serializable { 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static final long serialVersionUID = 0; 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski static final MemoryUsage NOT_AVAILABLE = new MemoryUsage(); 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski static int errorCount = 0; 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // These values are in 1kB increments (not 4kB like you'd expect). 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final int nativeSharedPages; 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final int javaSharedPages; 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final int otherSharedPages; 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final int nativePrivatePages; 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final int javaPrivatePages; 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final int otherPrivatePages; 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final int allocCount; 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final int allocSize; 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final int freedCount; 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final int freedSize; 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final long nativeHeapSize; 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public MemoryUsage(String line) { 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String[] parsed = line.split(","); 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nativeSharedPages = Integer.parseInt(parsed[1]); 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski javaSharedPages = Integer.parseInt(parsed[2]); 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski otherSharedPages = Integer.parseInt(parsed[3]); 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nativePrivatePages = Integer.parseInt(parsed[4]); 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski javaPrivatePages = Integer.parseInt(parsed[5]); 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski otherPrivatePages = Integer.parseInt(parsed[6]); 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski allocCount = Integer.parseInt(parsed[7]); 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski allocSize = Integer.parseInt(parsed[8]); 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski freedCount = Integer.parseInt(parsed[9]); 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski freedSize = Integer.parseInt(parsed[10]); 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nativeHeapSize = Long.parseLong(parsed[11]); 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MemoryUsage() { 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nativeSharedPages = -1; 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski javaSharedPages = -1; 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski otherSharedPages = -1; 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nativePrivatePages = -1; 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski javaPrivatePages = -1; 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski otherPrivatePages = -1; 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski allocCount = -1; 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski allocSize = -1; 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski freedCount = -1; 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski freedSize = -1; 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nativeHeapSize = -1; 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MemoryUsage(int nativeSharedPages, 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int javaSharedPages, 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int otherSharedPages, 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int nativePrivatePages, 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int javaPrivatePages, 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int otherPrivatePages, 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int allocCount, 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int allocSize, 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int freedCount, 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int freedSize, 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski long nativeHeapSize) { 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.nativeSharedPages = nativeSharedPages; 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.javaSharedPages = javaSharedPages; 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.otherSharedPages = otherSharedPages; 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.nativePrivatePages = nativePrivatePages; 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.javaPrivatePages = javaPrivatePages; 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.otherPrivatePages = otherPrivatePages; 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.allocCount = allocCount; 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.allocSize = allocSize; 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.freedCount = freedCount; 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.freedSize = freedSize; 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.nativeHeapSize = nativeHeapSize; 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MemoryUsage subtract(MemoryUsage baseline) { 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MemoryUsage( 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nativeSharedPages - baseline.nativeSharedPages, 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski javaSharedPages - baseline.javaSharedPages, 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski otherSharedPages - baseline.otherSharedPages, 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nativePrivatePages - baseline.nativePrivatePages, 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski javaPrivatePages - baseline.javaPrivatePages, 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski otherPrivatePages - baseline.otherPrivatePages, 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski allocCount - baseline.allocCount, 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski allocSize - baseline.allocSize, 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski freedCount - baseline.freedCount, 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski freedSize - baseline.freedSize, 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nativeHeapSize - baseline.nativeHeapSize); 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int javaHeapSize() { 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return allocSize - freedSize; 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int totalHeap() { 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return javaHeapSize() + (int) nativeHeapSize; 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int javaPagesInK() { 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return javaSharedPages + javaPrivatePages; 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int nativePagesInK() { 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return nativeSharedPages + nativePrivatePages; 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int otherPagesInK() { 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return otherSharedPages + otherPrivatePages; 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int totalPages() { 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return javaSharedPages + javaPrivatePages + nativeSharedPages + 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski nativePrivatePages + otherSharedPages + otherPrivatePages; 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Was this information available? 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski boolean isAvailable() { 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return nativeSharedPages != -1; 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Measures baseline memory usage. 155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski static MemoryUsage baseline() { 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return forClass(null); 158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static final String CLASS_PATH = "-Xbootclasspath" 161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + ":/system/framework/core.jar" 162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + ":/system/framework/ext.jar" 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + ":/system/framework/framework.jar" 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + ":/system/framework/framework-tests.jar" 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + ":/system/framework/services.jar" 166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + ":/system/framework/loadclass.jar"; 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static final String[] GET_DIRTY_PAGES = { 169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "adb", "shell", "dalvikvm", CLASS_PATH, "LoadClass" }; 170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Measures memory usage for the given class. 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski static MemoryUsage forClass(String className) { 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MeasureWithTimeout measurer = new MeasureWithTimeout(className); 176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new Thread(measurer).start(); 178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski synchronized (measurer) { 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (measurer.memoryUsage == null) { 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Wait up to 10s. 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski try { 183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski measurer.wait(30000); 184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } catch (InterruptedException e) { 185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski System.err.println("Interrupted waiting for measurement."); 186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e.printStackTrace(); 187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NOT_AVAILABLE; 188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If it's still null. 191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (measurer.memoryUsage == null) { 192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski System.err.println("Timed out while measuring " 193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + className + "."); 194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NOT_AVAILABLE; 195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski System.err.println("Got memory usage for " + className + "."); 199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return measurer.memoryUsage; 200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski static class MeasureWithTimeout implements Runnable { 204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final String className; 206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MemoryUsage memoryUsage = null; 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MeasureWithTimeout(String className) { 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this.className = className; 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void run() { 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MemoryUsage measured = measure(); 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski synchronized (this) { 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memoryUsage = measured; 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski notifyAll(); 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private MemoryUsage measure() { 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String[] commands = GET_DIRTY_PAGES; 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (className != null) { 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski List<String> commandList = new ArrayList<String>( 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski GET_DIRTY_PAGES.length + 1); 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski commandList.addAll(Arrays.asList(commands)); 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski commandList.add(className); 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski commands = commandList.toArray(new String[commandList.size()]); 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski try { 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final Process process = Runtime.getRuntime().exec(commands); 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final InputStream err = process.getErrorStream(); 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Send error output to stderr. 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Thread errThread = new Thread() { 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void run() { 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski copy(err, System.err); 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski }; 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski errThread.setDaemon(true); 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski errThread.start(); 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski BufferedReader in = new BufferedReader( 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new InputStreamReader(process.getInputStream())); 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String line = in.readLine(); 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (line == null || !line.startsWith("DECAFBAD,")) { 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski System.err.println("Got bad response for " + className 251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + ": " + line + "; command was " + Arrays.toString(commands)); 252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski errorCount += 1; 253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NOT_AVAILABLE; 254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski in.close(); 257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski err.close(); 258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski process.destroy(); 259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new MemoryUsage(line); 261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } catch (IOException e) { 262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski System.err.println("Error getting stats for " 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + className + "."); 264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e.printStackTrace(); 265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NOT_AVAILABLE; 266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Copies from one stream to another. 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static void copy(InputStream in, OutputStream out) { 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski byte[] buffer = new byte[1024]; 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int read; 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski try { 278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while ((read = in.read(buffer)) > -1) { 279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski out.write(buffer, 0, read); 280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } catch (IOException e) { 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski e.printStackTrace(); 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Measures memory usage information and stores it in the model. */ 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public static void main(String[] args) throws IOException, 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ClassNotFoundException { 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Root root = Root.fromFile(args[0]); 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root.baseline = baseline(); 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (LoadedClass loadedClass : root.loadedClasses.values()) { 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (loadedClass.systemClass) { 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski loadedClass.measureMemoryUsage(); 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski root.toFile(args[0]); 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 299