1 /* 2 * Copyright (C) 2007 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 package dalvik.system; 18 19 import java.io.FileDescriptor; 20 import java.io.IOException; 21 22 /** 23 * Provides access to some VM-specific debug features. Though this class and 24 * many of its members are public, this class is meant to be wrapped in a more 25 * friendly way for use by application developers. On the Android platform, the 26 * recommended way to access this functionality is through the class 27 * <code>android.os.Debug</code>. 28 * 29 * @hide 30 */ 31 public final class VMDebug { 32 /** 33 * flag for startMethodTracing(), which adds the results from 34 * startAllocCounting to the trace key file. 35 */ 36 public static final int TRACE_COUNT_ALLOCS = 1; 37 38 /* constants for getAllocCount */ 39 private static final int KIND_ALLOCATED_OBJECTS = 1<<0; 40 private static final int KIND_ALLOCATED_BYTES = 1<<1; 41 private static final int KIND_FREED_OBJECTS = 1<<2; 42 private static final int KIND_FREED_BYTES = 1<<3; 43 private static final int KIND_GC_INVOCATIONS = 1<<4; 44 private static final int KIND_CLASS_INIT_COUNT = 1<<5; 45 private static final int KIND_CLASS_INIT_TIME = 1<<6; 46 private static final int KIND_EXT_ALLOCATED_OBJECTS = 1<<12; 47 private static final int KIND_EXT_ALLOCATED_BYTES = 1<<13; 48 private static final int KIND_EXT_FREED_OBJECTS = 1<<14; 49 private static final int KIND_EXT_FREED_BYTES = 1<<15; 50 51 public static final int KIND_GLOBAL_ALLOCATED_OBJECTS = 52 KIND_ALLOCATED_OBJECTS; 53 public static final int KIND_GLOBAL_ALLOCATED_BYTES = 54 KIND_ALLOCATED_BYTES; 55 public static final int KIND_GLOBAL_FREED_OBJECTS = 56 KIND_FREED_OBJECTS; 57 public static final int KIND_GLOBAL_FREED_BYTES = 58 KIND_FREED_BYTES; 59 public static final int KIND_GLOBAL_GC_INVOCATIONS = 60 KIND_GC_INVOCATIONS; 61 public static final int KIND_GLOBAL_CLASS_INIT_COUNT = 62 KIND_CLASS_INIT_COUNT; 63 public static final int KIND_GLOBAL_CLASS_INIT_TIME = 64 KIND_CLASS_INIT_TIME; 65 public static final int KIND_GLOBAL_EXT_ALLOCATED_OBJECTS = 66 KIND_EXT_ALLOCATED_OBJECTS; 67 public static final int KIND_GLOBAL_EXT_ALLOCATED_BYTES = 68 KIND_EXT_ALLOCATED_BYTES; 69 public static final int KIND_GLOBAL_EXT_FREED_OBJECTS = 70 KIND_EXT_FREED_OBJECTS; 71 public static final int KIND_GLOBAL_EXT_FREED_BYTES = 72 KIND_EXT_FREED_BYTES; 73 74 public static final int KIND_THREAD_ALLOCATED_OBJECTS = 75 KIND_ALLOCATED_OBJECTS << 16; 76 public static final int KIND_THREAD_ALLOCATED_BYTES = 77 KIND_ALLOCATED_BYTES << 16; 78 public static final int KIND_THREAD_FREED_OBJECTS = 79 KIND_FREED_OBJECTS << 16; 80 public static final int KIND_THREAD_FREED_BYTES = 81 KIND_FREED_BYTES << 16; 82 public static final int KIND_THREAD_GC_INVOCATIONS = 83 KIND_GC_INVOCATIONS << 16; 84 public static final int KIND_THREAD_CLASS_INIT_COUNT = 85 KIND_CLASS_INIT_COUNT << 16; 86 public static final int KIND_THREAD_CLASS_INIT_TIME = 87 KIND_CLASS_INIT_TIME << 16; 88 public static final int KIND_THREAD_EXT_ALLOCATED_OBJECTS = 89 KIND_EXT_ALLOCATED_OBJECTS << 16; 90 public static final int KIND_THREAD_EXT_ALLOCATED_BYTES = 91 KIND_EXT_ALLOCATED_BYTES << 16; 92 public static final int KIND_THREAD_EXT_FREED_OBJECTS = 93 KIND_EXT_FREED_OBJECTS << 16; 94 public static final int KIND_THREAD_EXT_FREED_BYTES = 95 KIND_EXT_FREED_BYTES << 16; 96 97 public static final int KIND_ALL_COUNTS = 0xffffffff; 98 99 /* all methods are static */ VMDebug()100 private VMDebug() {} 101 102 /** 103 * Returns the time since the last known debugger activity. 104 * 105 * @return the time in milliseconds, or -1 if the debugger is not connected 106 */ lastDebuggerActivity()107 public static native long lastDebuggerActivity(); 108 109 /** 110 * Determines if debugging is enabled in this VM. If debugging is not 111 * enabled, a debugger cannot be attached. 112 * 113 * @return true if debugging is enabled 114 */ isDebuggingEnabled()115 public static native boolean isDebuggingEnabled(); 116 117 /** 118 * Determines if a debugger is currently attached. 119 * 120 * @return true if (and only if) a debugger is connected 121 */ isDebuggerConnected()122 public static native boolean isDebuggerConnected(); 123 124 /** 125 * Returns an array of strings that identify VM features. This is 126 * used by DDMS to determine what sorts of operations the VM can 127 * perform. 128 */ getVmFeatureList()129 public static native String[] getVmFeatureList(); 130 131 /** 132 * Start method tracing with default name, size, and with <code>0</code> 133 * flags. 134 * 135 * @deprecated Not used, not needed. 136 */ 137 @Deprecated startMethodTracing()138 public static void startMethodTracing() { 139 throw new UnsupportedOperationException(); 140 } 141 142 /** 143 * Start method tracing, specifying a file name as well as a default 144 * buffer size. See <a 145 * href="{@docRoot}guide/developing/tools/traceview.html"> Running the 146 * Traceview Debugging Program</a> for information about reading 147 * trace files. 148 * 149 * <p>You can use either a fully qualified path and 150 * name, or just a name. If only a name is specified, the file will 151 * be created under the /sdcard/ directory. If a name is not given, 152 * the default is /sdcard/dmtrace.trace.</p> 153 * 154 * @param traceFileName name to give the trace file 155 * @param bufferSize the maximum size of both files combined. If passed 156 * as <code>0</code>, it defaults to 8MB. 157 * @param flags flags to control method tracing. The only one that 158 * is currently defined is {@link #TRACE_COUNT_ALLOCS}. 159 * @param samplingEnabled if true, sample profiling is enabled. Otherwise, 160 * method instrumentation is used. 161 * @param intervalUs the time between samples in microseconds when 162 * sampling is enabled. 163 */ startMethodTracing(String traceFileName, int bufferSize, int flags, boolean samplingEnabled, int intervalUs)164 public static void startMethodTracing(String traceFileName, int bufferSize, int flags, boolean samplingEnabled, int intervalUs) { 165 startMethodTracingFilename(traceFileName, checkBufferSize(bufferSize), flags, samplingEnabled, intervalUs); 166 } 167 168 /** 169 * Like startMethodTracing(String, int, int), but taking an already-opened 170 * FileDescriptor in which the trace is written. The file name is also 171 * supplied simply for logging. Makes a dup of the file descriptor. 172 */ startMethodTracing(String traceFileName, FileDescriptor fd, int bufferSize, int flags, boolean samplingEnabled, int intervalUs)173 public static void startMethodTracing(String traceFileName, FileDescriptor fd, int bufferSize, int flags, boolean samplingEnabled, int intervalUs) { 174 if (fd == null) { 175 throw new NullPointerException("fd == null"); 176 } 177 startMethodTracingFd(traceFileName, fd, checkBufferSize(bufferSize), flags, samplingEnabled, intervalUs); 178 } 179 180 /** 181 * Starts method tracing without a backing file. When stopMethodTracing 182 * is called, the result is sent directly to DDMS. (If DDMS is not 183 * attached when tracing ends, the profiling data will be discarded.) 184 */ startMethodTracingDdms(int bufferSize, int flags, boolean samplingEnabled, int intervalUs)185 public static void startMethodTracingDdms(int bufferSize, int flags, boolean samplingEnabled, int intervalUs) { 186 startMethodTracingDdmsImpl(checkBufferSize(bufferSize), flags, samplingEnabled, intervalUs); 187 } 188 checkBufferSize(int bufferSize)189 private static int checkBufferSize(int bufferSize) { 190 if (bufferSize == 0) { 191 // Default to 8MB per the documentation. 192 bufferSize = 8 * 1024 * 1024; 193 } 194 if (bufferSize < 1024) { 195 throw new IllegalArgumentException("buffer size < 1024: " + bufferSize); 196 } 197 return bufferSize; 198 } 199 startMethodTracingDdmsImpl(int bufferSize, int flags, boolean samplingEnabled, int intervalUs)200 private static native void startMethodTracingDdmsImpl(int bufferSize, int flags, boolean samplingEnabled, int intervalUs); startMethodTracingFd(String traceFileName, FileDescriptor fd, int bufferSize, int flags, boolean samplingEnabled, int intervalUs)201 private static native void startMethodTracingFd(String traceFileName, FileDescriptor fd, int bufferSize, int flags, boolean samplingEnabled, int intervalUs); startMethodTracingFilename(String traceFileName, int bufferSize, int flags, boolean samplingEnabled, int intervalUs)202 private static native void startMethodTracingFilename(String traceFileName, int bufferSize, int flags, boolean samplingEnabled, int intervalUs); 203 204 /** 205 * Determine whether method tracing is currently active and what type is 206 * active. 207 */ getMethodTracingMode()208 public static native int getMethodTracingMode(); 209 210 /** 211 * Stops method tracing. 212 */ stopMethodTracing()213 public static native void stopMethodTracing(); 214 215 /** 216 * Starts sending Dalvik method trace info to the emulator. 217 */ startEmulatorTracing()218 public static native void startEmulatorTracing(); 219 220 /** 221 * Stops sending Dalvik method trace info to the emulator. 222 */ stopEmulatorTracing()223 public static native void stopEmulatorTracing(); 224 225 /** 226 * Get an indication of thread CPU usage. The value returned indicates the 227 * amount of time that the current thread has spent executing code or 228 * waiting for certain types of I/O. 229 * <p> 230 * The time is expressed in nanoseconds, and is only meaningful when 231 * compared to the result from an earlier call. Note that nanosecond 232 * resolution does not imply nanosecond accuracy. 233 * 234 * @return the CPU usage. A value of -1 means the system does not support 235 * this feature. 236 */ threadCpuTimeNanos()237 public static native long threadCpuTimeNanos(); 238 239 /** 240 * Count the number and aggregate size of memory allocations between 241 * two points. 242 */ startAllocCounting()243 public static native void startAllocCounting(); stopAllocCounting()244 public static native void stopAllocCounting(); getAllocCount(int kind)245 public static native int getAllocCount(int kind); resetAllocCount(int kinds)246 public static native void resetAllocCount(int kinds); 247 248 /** 249 * This method exists for binary compatibility. It was part of 250 * the allocation limits API which was removed in Android 3.0 (Honeycomb). 251 */ 252 @Deprecated setAllocationLimit(int limit)253 public static int setAllocationLimit(int limit) { 254 return -1; 255 } 256 257 /** 258 * This method exists for binary compatibility. It was part of 259 * the allocation limits API which was removed in Android 3.0 (Honeycomb). 260 */ 261 @Deprecated setGlobalAllocationLimit(int limit)262 public static int setGlobalAllocationLimit(int limit) { 263 return -1; 264 } 265 266 /** 267 * Count the number of instructions executed between two points. 268 */ startInstructionCounting()269 public static native void startInstructionCounting(); stopInstructionCounting()270 public static native void stopInstructionCounting(); getInstructionCount(int[] counts)271 public static native void getInstructionCount(int[] counts); resetInstructionCount()272 public static native void resetInstructionCount(); 273 274 /** 275 * Dumps a list of loaded class to the log file. 276 */ printLoadedClasses(int flags)277 public static native void printLoadedClasses(int flags); 278 279 /** 280 * Gets the number of loaded classes. 281 * 282 * @return the number of loaded classes 283 */ getLoadedClassCount()284 public static native int getLoadedClassCount(); 285 286 /** 287 * Dumps "hprof" data to the specified file. This may cause a GC. 288 * 289 * The VM may create a temporary file in the same directory. 290 * 291 * @param filename Full pathname of output file (e.g. "/sdcard/dump.hprof"). 292 * @throws UnsupportedOperationException if the VM was built without 293 * HPROF support. 294 * @throws IOException if an error occurs while opening or writing files. 295 */ dumpHprofData(String filename)296 public static void dumpHprofData(String filename) throws IOException { 297 if (filename == null) { 298 throw new NullPointerException("filename == null"); 299 } 300 dumpHprofData(filename, null); 301 } 302 303 /** 304 * Collects "hprof" heap data and sends it to DDMS. This may cause a GC. 305 * 306 * @throws UnsupportedOperationException if the VM was built without 307 * HPROF support. 308 */ dumpHprofDataDdms()309 public static native void dumpHprofDataDdms(); 310 311 /** 312 * Dumps "hprof" heap data to a file, by name or descriptor. 313 * 314 * @param fileName Name of output file. If fd is non-null, the 315 * file name is only used in log messages (and may be null). 316 * @param fd Descriptor of open file that will receive the output. 317 * If this is null, the fileName is used instead. 318 */ dumpHprofData(String fileName, FileDescriptor fd)319 public static native void dumpHprofData(String fileName, FileDescriptor fd) 320 throws IOException; 321 322 /** 323 * Primes the register map cache. 324 */ cacheRegisterMap(String classAndMethodDesc)325 public static native boolean cacheRegisterMap(String classAndMethodDesc); 326 327 /** 328 * Dumps the contents of the VM reference tables (e.g. JNI locals and 329 * globals) to the log file. 330 */ dumpReferenceTables()331 public static native void dumpReferenceTables(); 332 333 /** 334 * Crashes the VM. Seriously. Dumps the interpreter stack trace for 335 * the current thread and then aborts the VM so you can see the native 336 * stack trace. Useful for figuring out how you got somewhere when 337 * lots of native code is involved. 338 */ crash()339 public static native void crash(); 340 341 /** 342 * Together with gdb, provide a handy way to stop the VM at user-tagged 343 * locations. 344 */ infopoint(int id)345 public static native void infopoint(int id); 346 347 /* 348 * Fake method, inserted into dmtrace output when the garbage collector 349 * runs. Not actually called. 350 */ startGC()351 private static void startGC() {} 352 353 /* 354 * Fake method, inserted into dmtrace output during class preparation 355 * (loading and linking, but not verification or initialization). Not 356 * actually called. 357 */ startClassPrep()358 private static void startClassPrep() {} 359 360 /** 361 * Counts the instances of a class. 362 * 363 * @param klass the class to be counted. 364 * @param assignable if false, direct instances of klass are 365 * counted. If true, instances that are 366 * assignable to klass, as defined by 367 * {@link Class#isAssignableFrom} are counted. 368 * @return the number of matching instances. 369 */ countInstancesOfClass(Class klass, boolean assignable)370 public static native long countInstancesOfClass(Class klass, boolean assignable); 371 372 /** 373 * Export the heap per-space stats for dumpsys meminfo. 374 * 375 * The content of the array is: 376 * 377 * <pre> 378 * data[0] : the application heap space size 379 * data[1] : the application heap space allocated bytes 380 * data[2] : the application heap space free bytes 381 * data[3] : the zygote heap space size 382 * data[4] : the zygote heap space allocated size 383 * data[5] : the zygote heap space free size 384 * data[6] : the large object space size 385 * data[7] : the large object space allocated bytes 386 * data[8] : the large object space free bytes 387 * </pre> 388 * 389 * @param data the array into which the stats are written. 390 */ getHeapSpaceStats(long[] data)391 public static native void getHeapSpaceStats(long[] data); 392 } 393