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 android.os; 18 19 import android.app.AppGlobals; 20 import android.content.Context; 21 import android.util.Log; 22 23 import com.android.internal.util.FastPrintWriter; 24 import com.android.internal.util.TypedProperties; 25 26 import dalvik.bytecode.OpcodeInfo; 27 import dalvik.system.VMDebug; 28 29 import org.apache.harmony.dalvik.ddmc.Chunk; 30 import org.apache.harmony.dalvik.ddmc.ChunkHandler; 31 import org.apache.harmony.dalvik.ddmc.DdmServer; 32 33 import java.io.File; 34 import java.io.FileDescriptor; 35 import java.io.FileNotFoundException; 36 import java.io.FileOutputStream; 37 import java.io.FileReader; 38 import java.io.IOException; 39 import java.io.PrintWriter; 40 import java.io.Reader; 41 import java.lang.annotation.ElementType; 42 import java.lang.annotation.Retention; 43 import java.lang.annotation.RetentionPolicy; 44 import java.lang.annotation.Target; 45 import java.lang.reflect.Field; 46 import java.lang.reflect.Modifier; 47 import java.util.HashMap; 48 import java.util.Map; 49 50 51 52 53 /** 54 * Provides various debugging methods for Android applications, including 55 * tracing and allocation counts. 56 * <p><strong>Logging Trace Files</strong></p> 57 * <p>Debug can create log files that give details about an application, such as 58 * a call stack and start/stop times for any running methods. See <a 59 href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for 60 * information about reading trace files. To start logging trace files, call one 61 * of the startMethodTracing() methods. To stop tracing, call 62 * {@link #stopMethodTracing()}. 63 */ 64 public final class Debug 65 { 66 private static final String TAG = "Debug"; 67 68 /** 69 * Flags for startMethodTracing(). These can be ORed together. 70 * 71 * TRACE_COUNT_ALLOCS adds the results from startAllocCounting to the 72 * trace key file. 73 * 74 * @deprecated Accurate counting is a burden on the runtime and may be removed. 75 */ 76 @Deprecated 77 public static final int TRACE_COUNT_ALLOCS = VMDebug.TRACE_COUNT_ALLOCS; 78 79 /** 80 * Flags for printLoadedClasses(). Default behavior is to only show 81 * the class name. 82 */ 83 public static final int SHOW_FULL_DETAIL = 1; 84 public static final int SHOW_CLASSLOADER = (1 << 1); 85 public static final int SHOW_INITIALIZED = (1 << 2); 86 87 // set/cleared by waitForDebugger() 88 private static volatile boolean mWaiting = false; 89 Debug()90 private Debug() {} 91 92 /* 93 * How long to wait for the debugger to finish sending requests. I've 94 * seen this hit 800msec on the device while waiting for a response 95 * to travel over USB and get processed, so we take that and add 96 * half a second. 97 */ 98 private static final int MIN_DEBUGGER_IDLE = 1300; // msec 99 100 /* how long to sleep when polling for activity */ 101 private static final int SPIN_DELAY = 200; // msec 102 103 /** 104 * Default trace file path and file 105 */ 106 private static final String DEFAULT_TRACE_BODY = "dmtrace"; 107 private static final String DEFAULT_TRACE_EXTENSION = ".trace"; 108 109 /** 110 * This class is used to retrieved various statistics about the memory mappings for this 111 * process. The returned info is broken down by dalvik, native, and other. All results are in kB. 112 */ 113 public static class MemoryInfo implements Parcelable { 114 /** The proportional set size for dalvik heap. (Doesn't include other Dalvik overhead.) */ 115 public int dalvikPss; 116 /** The proportional set size that is swappable for dalvik heap. */ 117 /** @hide We may want to expose this, eventually. */ 118 public int dalvikSwappablePss; 119 /** The private dirty pages used by dalvik heap. */ 120 public int dalvikPrivateDirty; 121 /** The shared dirty pages used by dalvik heap. */ 122 public int dalvikSharedDirty; 123 /** The private clean pages used by dalvik heap. */ 124 /** @hide We may want to expose this, eventually. */ 125 public int dalvikPrivateClean; 126 /** The shared clean pages used by dalvik heap. */ 127 /** @hide We may want to expose this, eventually. */ 128 public int dalvikSharedClean; 129 /** The dirty dalvik pages that have been swapped out. */ 130 /** @hide We may want to expose this, eventually. */ 131 public int dalvikSwappedOut; 132 /** The dirty dalvik pages that have been swapped out, proportional. */ 133 /** @hide We may want to expose this, eventually. */ 134 public int dalvikSwappedOutPss; 135 136 /** The proportional set size for the native heap. */ 137 public int nativePss; 138 /** The proportional set size that is swappable for the native heap. */ 139 /** @hide We may want to expose this, eventually. */ 140 public int nativeSwappablePss; 141 /** The private dirty pages used by the native heap. */ 142 public int nativePrivateDirty; 143 /** The shared dirty pages used by the native heap. */ 144 public int nativeSharedDirty; 145 /** The private clean pages used by the native heap. */ 146 /** @hide We may want to expose this, eventually. */ 147 public int nativePrivateClean; 148 /** The shared clean pages used by the native heap. */ 149 /** @hide We may want to expose this, eventually. */ 150 public int nativeSharedClean; 151 /** The dirty native pages that have been swapped out. */ 152 /** @hide We may want to expose this, eventually. */ 153 public int nativeSwappedOut; 154 /** The dirty native pages that have been swapped out, proportional. */ 155 /** @hide We may want to expose this, eventually. */ 156 public int nativeSwappedOutPss; 157 158 /** The proportional set size for everything else. */ 159 public int otherPss; 160 /** The proportional set size that is swappable for everything else. */ 161 /** @hide We may want to expose this, eventually. */ 162 public int otherSwappablePss; 163 /** The private dirty pages used by everything else. */ 164 public int otherPrivateDirty; 165 /** The shared dirty pages used by everything else. */ 166 public int otherSharedDirty; 167 /** The private clean pages used by everything else. */ 168 /** @hide We may want to expose this, eventually. */ 169 public int otherPrivateClean; 170 /** The shared clean pages used by everything else. */ 171 /** @hide We may want to expose this, eventually. */ 172 public int otherSharedClean; 173 /** The dirty pages used by anyting else that have been swapped out. */ 174 /** @hide We may want to expose this, eventually. */ 175 public int otherSwappedOut; 176 /** The dirty pages used by anyting else that have been swapped out, proportional. */ 177 /** @hide We may want to expose this, eventually. */ 178 public int otherSwappedOutPss; 179 180 /** Whether the kernel reports proportional swap usage */ 181 /** @hide */ 182 public boolean hasSwappedOutPss; 183 184 /** @hide */ 185 public static final int HEAP_UNKNOWN = 0; 186 /** @hide */ 187 public static final int HEAP_DALVIK = 1; 188 /** @hide */ 189 public static final int HEAP_NATIVE = 2; 190 191 /** @hide */ 192 public static final int OTHER_DALVIK_OTHER = 0; 193 /** @hide */ 194 public static final int OTHER_STACK = 1; 195 /** @hide */ 196 public static final int OTHER_CURSOR = 2; 197 /** @hide */ 198 public static final int OTHER_ASHMEM = 3; 199 /** @hide */ 200 public static final int OTHER_GL_DEV = 4; 201 /** @hide */ 202 public static final int OTHER_UNKNOWN_DEV = 5; 203 /** @hide */ 204 public static final int OTHER_SO = 6; 205 /** @hide */ 206 public static final int OTHER_JAR = 7; 207 /** @hide */ 208 public static final int OTHER_APK = 8; 209 /** @hide */ 210 public static final int OTHER_TTF = 9; 211 /** @hide */ 212 public static final int OTHER_DEX = 10; 213 /** @hide */ 214 public static final int OTHER_OAT = 11; 215 /** @hide */ 216 public static final int OTHER_ART = 12; 217 /** @hide */ 218 public static final int OTHER_UNKNOWN_MAP = 13; 219 /** @hide */ 220 public static final int OTHER_GRAPHICS = 14; 221 /** @hide */ 222 public static final int OTHER_GL = 15; 223 /** @hide */ 224 public static final int OTHER_OTHER_MEMTRACK = 16; 225 226 // Needs to be declared here for the DVK_STAT ranges below. 227 /** @hide */ 228 public static final int NUM_OTHER_STATS = 17; 229 230 // Dalvik subsections. 231 /** @hide */ 232 public static final int OTHER_DALVIK_NORMAL = 17; 233 /** @hide */ 234 public static final int OTHER_DALVIK_LARGE = 18; 235 /** @hide */ 236 public static final int OTHER_DALVIK_ZYGOTE = 19; 237 /** @hide */ 238 public static final int OTHER_DALVIK_NON_MOVING = 20; 239 // Section begins and ends for dumpsys, relative to the DALVIK categories. 240 /** @hide */ 241 public static final int OTHER_DVK_STAT_DALVIK_START = 242 OTHER_DALVIK_NORMAL - NUM_OTHER_STATS; 243 /** @hide */ 244 public static final int OTHER_DVK_STAT_DALVIK_END = 245 OTHER_DALVIK_NON_MOVING - NUM_OTHER_STATS; 246 247 // Dalvik Other subsections. 248 /** @hide */ 249 public static final int OTHER_DALVIK_OTHER_LINEARALLOC = 21; 250 /** @hide */ 251 public static final int OTHER_DALVIK_OTHER_ACCOUNTING = 22; 252 /** @hide */ 253 public static final int OTHER_DALVIK_OTHER_CODE_CACHE = 23; 254 /** @hide */ 255 public static final int OTHER_DALVIK_OTHER_COMPILER_METADATA = 24; 256 /** @hide */ 257 public static final int OTHER_DALVIK_OTHER_INDIRECT_REFERENCE_TABLE = 25; 258 /** @hide */ 259 public static final int OTHER_DVK_STAT_DALVIK_OTHER_START = 260 OTHER_DALVIK_OTHER_LINEARALLOC - NUM_OTHER_STATS; 261 /** @hide */ 262 public static final int OTHER_DVK_STAT_DALVIK_OTHER_END = 263 OTHER_DALVIK_OTHER_INDIRECT_REFERENCE_TABLE - NUM_OTHER_STATS; 264 265 // Dex subsections (Boot vdex, App dex, and App vdex). 266 /** @hide */ 267 public static final int OTHER_DEX_BOOT_VDEX = 26; 268 /** @hide */ 269 public static final int OTHER_DEX_APP_DEX = 27; 270 /** @hide */ 271 public static final int OTHER_DEX_APP_VDEX = 28; 272 /** @hide */ 273 public static final int OTHER_DVK_STAT_DEX_START = OTHER_DEX_BOOT_VDEX - NUM_OTHER_STATS; 274 /** @hide */ 275 public static final int OTHER_DVK_STAT_DEX_END = OTHER_DEX_APP_VDEX - NUM_OTHER_STATS; 276 277 // Art subsections (App image, boot image). 278 /** @hide */ 279 public static final int OTHER_ART_APP = 29; 280 /** @hide */ 281 public static final int OTHER_ART_BOOT = 30; 282 /** @hide */ 283 public static final int OTHER_DVK_STAT_ART_START = OTHER_ART_APP - NUM_OTHER_STATS; 284 /** @hide */ 285 public static final int OTHER_DVK_STAT_ART_END = OTHER_ART_BOOT - NUM_OTHER_STATS; 286 287 /** @hide */ 288 public static final int NUM_DVK_STATS = 14; 289 290 /** @hide */ 291 public static final int NUM_CATEGORIES = 8; 292 293 /** @hide */ 294 public static final int offsetPss = 0; 295 /** @hide */ 296 public static final int offsetSwappablePss = 1; 297 /** @hide */ 298 public static final int offsetPrivateDirty = 2; 299 /** @hide */ 300 public static final int offsetSharedDirty = 3; 301 /** @hide */ 302 public static final int offsetPrivateClean = 4; 303 /** @hide */ 304 public static final int offsetSharedClean = 5; 305 /** @hide */ 306 public static final int offsetSwappedOut = 6; 307 /** @hide */ 308 public static final int offsetSwappedOutPss = 7; 309 310 private int[] otherStats = new int[(NUM_OTHER_STATS+NUM_DVK_STATS)*NUM_CATEGORIES]; 311 MemoryInfo()312 public MemoryInfo() { 313 } 314 315 /** 316 * Return total PSS memory usage in kB. 317 */ getTotalPss()318 public int getTotalPss() { 319 return dalvikPss + nativePss + otherPss + getTotalSwappedOutPss(); 320 } 321 322 /** 323 * @hide Return total PSS memory usage in kB. 324 */ getTotalUss()325 public int getTotalUss() { 326 return dalvikPrivateClean + dalvikPrivateDirty 327 + nativePrivateClean + nativePrivateDirty 328 + otherPrivateClean + otherPrivateDirty; 329 } 330 331 /** 332 * Return total PSS memory usage in kB mapping a file of one of the following extension: 333 * .so, .jar, .apk, .ttf, .dex, .odex, .oat, .art . 334 */ getTotalSwappablePss()335 public int getTotalSwappablePss() { 336 return dalvikSwappablePss + nativeSwappablePss + otherSwappablePss; 337 } 338 339 /** 340 * Return total private dirty memory usage in kB. 341 */ getTotalPrivateDirty()342 public int getTotalPrivateDirty() { 343 return dalvikPrivateDirty + nativePrivateDirty + otherPrivateDirty; 344 } 345 346 /** 347 * Return total shared dirty memory usage in kB. 348 */ getTotalSharedDirty()349 public int getTotalSharedDirty() { 350 return dalvikSharedDirty + nativeSharedDirty + otherSharedDirty; 351 } 352 353 /** 354 * Return total shared clean memory usage in kB. 355 */ getTotalPrivateClean()356 public int getTotalPrivateClean() { 357 return dalvikPrivateClean + nativePrivateClean + otherPrivateClean; 358 } 359 360 /** 361 * Return total shared clean memory usage in kB. 362 */ getTotalSharedClean()363 public int getTotalSharedClean() { 364 return dalvikSharedClean + nativeSharedClean + otherSharedClean; 365 } 366 367 /** 368 * Return total swapped out memory in kB. 369 * @hide 370 */ getTotalSwappedOut()371 public int getTotalSwappedOut() { 372 return dalvikSwappedOut + nativeSwappedOut + otherSwappedOut; 373 } 374 375 /** 376 * Return total swapped out memory in kB, proportional. 377 * @hide 378 */ getTotalSwappedOutPss()379 public int getTotalSwappedOutPss() { 380 return dalvikSwappedOutPss + nativeSwappedOutPss + otherSwappedOutPss; 381 } 382 383 /** @hide */ getOtherPss(int which)384 public int getOtherPss(int which) { 385 return otherStats[which*NUM_CATEGORIES + offsetPss]; 386 } 387 388 389 /** @hide */ getOtherSwappablePss(int which)390 public int getOtherSwappablePss(int which) { 391 return otherStats[which*NUM_CATEGORIES + offsetSwappablePss]; 392 } 393 394 395 /** @hide */ getOtherPrivateDirty(int which)396 public int getOtherPrivateDirty(int which) { 397 return otherStats[which*NUM_CATEGORIES + offsetPrivateDirty]; 398 } 399 400 /** @hide */ getOtherSharedDirty(int which)401 public int getOtherSharedDirty(int which) { 402 return otherStats[which*NUM_CATEGORIES + offsetSharedDirty]; 403 } 404 405 /** @hide */ getOtherPrivateClean(int which)406 public int getOtherPrivateClean(int which) { 407 return otherStats[which*NUM_CATEGORIES + offsetPrivateClean]; 408 } 409 410 /** @hide */ getOtherPrivate(int which)411 public int getOtherPrivate(int which) { 412 return getOtherPrivateClean(which) + getOtherPrivateDirty(which); 413 } 414 415 /** @hide */ getOtherSharedClean(int which)416 public int getOtherSharedClean(int which) { 417 return otherStats[which*NUM_CATEGORIES + offsetSharedClean]; 418 } 419 420 /** @hide */ getOtherSwappedOut(int which)421 public int getOtherSwappedOut(int which) { 422 return otherStats[which*NUM_CATEGORIES + offsetSwappedOut]; 423 } 424 425 /** @hide */ getOtherSwappedOutPss(int which)426 public int getOtherSwappedOutPss(int which) { 427 return otherStats[which*NUM_CATEGORIES + offsetSwappedOutPss]; 428 } 429 430 /** @hide */ getOtherLabel(int which)431 public static String getOtherLabel(int which) { 432 switch (which) { 433 case OTHER_DALVIK_OTHER: return "Dalvik Other"; 434 case OTHER_STACK: return "Stack"; 435 case OTHER_CURSOR: return "Cursor"; 436 case OTHER_ASHMEM: return "Ashmem"; 437 case OTHER_GL_DEV: return "Gfx dev"; 438 case OTHER_UNKNOWN_DEV: return "Other dev"; 439 case OTHER_SO: return ".so mmap"; 440 case OTHER_JAR: return ".jar mmap"; 441 case OTHER_APK: return ".apk mmap"; 442 case OTHER_TTF: return ".ttf mmap"; 443 case OTHER_DEX: return ".dex mmap"; 444 case OTHER_OAT: return ".oat mmap"; 445 case OTHER_ART: return ".art mmap"; 446 case OTHER_UNKNOWN_MAP: return "Other mmap"; 447 case OTHER_GRAPHICS: return "EGL mtrack"; 448 case OTHER_GL: return "GL mtrack"; 449 case OTHER_OTHER_MEMTRACK: return "Other mtrack"; 450 case OTHER_DALVIK_NORMAL: return ".Heap"; 451 case OTHER_DALVIK_LARGE: return ".LOS"; 452 case OTHER_DALVIK_ZYGOTE: return ".Zygote"; 453 case OTHER_DALVIK_NON_MOVING: return ".NonMoving"; 454 case OTHER_DALVIK_OTHER_LINEARALLOC: return ".LinearAlloc"; 455 case OTHER_DALVIK_OTHER_ACCOUNTING: return ".GC"; 456 case OTHER_DALVIK_OTHER_CODE_CACHE: return ".JITCache"; 457 case OTHER_DALVIK_OTHER_COMPILER_METADATA: return ".CompilerMetadata"; 458 case OTHER_DALVIK_OTHER_INDIRECT_REFERENCE_TABLE: return ".IndirectRef"; 459 case OTHER_DEX_BOOT_VDEX: return ".Boot vdex"; 460 case OTHER_DEX_APP_DEX: return ".App dex"; 461 case OTHER_DEX_APP_VDEX: return ".App vdex"; 462 case OTHER_ART_APP: return ".App art"; 463 case OTHER_ART_BOOT: return ".Boot art"; 464 default: return "????"; 465 } 466 } 467 468 /** 469 * Returns the value of a particular memory statistic or {@code null} if no 470 * such memory statistic exists. 471 * 472 * <p>The following table lists the memory statistics that are supported. 473 * Note that memory statistics may be added or removed in a future API level.</p> 474 * 475 * <table> 476 * <thead> 477 * <tr> 478 * <th>Memory statistic name</th> 479 * <th>Meaning</th> 480 * <th>Example</th> 481 * <th>Supported (API Levels)</th> 482 * </tr> 483 * </thead> 484 * <tbody> 485 * <tr> 486 * <td>summary.java-heap</td> 487 * <td>The private Java Heap usage in kB. This corresponds to the Java Heap field 488 * in the App Summary section output by dumpsys meminfo.</td> 489 * <td>{@code 1442}</td> 490 * <td>23</td> 491 * </tr> 492 * <tr> 493 * <td>summary.native-heap</td> 494 * <td>The private Native Heap usage in kB. This corresponds to the Native Heap 495 * field in the App Summary section output by dumpsys meminfo.</td> 496 * <td>{@code 1442}</td> 497 * <td>23</td> 498 * </tr> 499 * <tr> 500 * <td>summary.code</td> 501 * <td>The memory usage for static code and resources in kB. This corresponds to 502 * the Code field in the App Summary section output by dumpsys meminfo.</td> 503 * <td>{@code 1442}</td> 504 * <td>23</td> 505 * </tr> 506 * <tr> 507 * <td>summary.stack</td> 508 * <td>The stack usage in kB. This corresponds to the Stack field in the 509 * App Summary section output by dumpsys meminfo.</td> 510 * <td>{@code 1442}</td> 511 * <td>23</td> 512 * </tr> 513 * <tr> 514 * <td>summary.graphics</td> 515 * <td>The graphics usage in kB. This corresponds to the Graphics field in the 516 * App Summary section output by dumpsys meminfo.</td> 517 * <td>{@code 1442}</td> 518 * <td>23</td> 519 * </tr> 520 * <tr> 521 * <td>summary.private-other</td> 522 * <td>Other private memory usage in kB. This corresponds to the Private Other 523 * field output in the App Summary section by dumpsys meminfo.</td> 524 * <td>{@code 1442}</td> 525 * <td>23</td> 526 * </tr> 527 * <tr> 528 * <td>summary.system</td> 529 * <td>Shared and system memory usage in kB. This corresponds to the System 530 * field output in the App Summary section by dumpsys meminfo.</td> 531 * <td>{@code 1442}</td> 532 * <td>23</td> 533 * </tr> 534 * <tr> 535 * <td>summary.total-pss</td> 536 * <td>Total PPS memory usage in kB.</td> 537 * <td>{@code 1442}</td> 538 * <td>23</td> 539 * </tr> 540 * <tr> 541 * <td>summary.total-swap</td> 542 * <td>Total swap usage in kB.</td> 543 * <td>{@code 1442}</td> 544 * <td>23</td> 545 * </tr> 546 * </tbody> 547 * </table> 548 */ getMemoryStat(String statName)549 public String getMemoryStat(String statName) { 550 switch(statName) { 551 case "summary.java-heap": 552 return Integer.toString(getSummaryJavaHeap()); 553 case "summary.native-heap": 554 return Integer.toString(getSummaryNativeHeap()); 555 case "summary.code": 556 return Integer.toString(getSummaryCode()); 557 case "summary.stack": 558 return Integer.toString(getSummaryStack()); 559 case "summary.graphics": 560 return Integer.toString(getSummaryGraphics()); 561 case "summary.private-other": 562 return Integer.toString(getSummaryPrivateOther()); 563 case "summary.system": 564 return Integer.toString(getSummarySystem()); 565 case "summary.total-pss": 566 return Integer.toString(getSummaryTotalPss()); 567 case "summary.total-swap": 568 return Integer.toString(getSummaryTotalSwap()); 569 default: 570 return null; 571 } 572 } 573 574 /** 575 * Returns a map of the names/values of the memory statistics 576 * that {@link #getMemoryStat(String)} supports. 577 * 578 * @return a map of the names/values of the supported memory statistics. 579 */ getMemoryStats()580 public Map<String, String> getMemoryStats() { 581 Map<String, String> stats = new HashMap<String, String>(); 582 stats.put("summary.java-heap", Integer.toString(getSummaryJavaHeap())); 583 stats.put("summary.native-heap", Integer.toString(getSummaryNativeHeap())); 584 stats.put("summary.code", Integer.toString(getSummaryCode())); 585 stats.put("summary.stack", Integer.toString(getSummaryStack())); 586 stats.put("summary.graphics", Integer.toString(getSummaryGraphics())); 587 stats.put("summary.private-other", Integer.toString(getSummaryPrivateOther())); 588 stats.put("summary.system", Integer.toString(getSummarySystem())); 589 stats.put("summary.total-pss", Integer.toString(getSummaryTotalPss())); 590 stats.put("summary.total-swap", Integer.toString(getSummaryTotalSwap())); 591 return stats; 592 } 593 594 /** 595 * Pss of Java Heap bytes in KB due to the application. 596 * Notes: 597 * * OTHER_ART is the boot image. Anything private here is blamed on 598 * the application, not the system. 599 * * dalvikPrivateDirty includes private zygote, which means the 600 * application dirtied something allocated by the zygote. We blame 601 * the application for that memory, not the system. 602 * * Does not include OTHER_DALVIK_OTHER, which is considered VM 603 * Overhead and lumped into Private Other. 604 * * We don't include dalvikPrivateClean, because there should be no 605 * such thing as private clean for the Java Heap. 606 * @hide 607 */ getSummaryJavaHeap()608 public int getSummaryJavaHeap() { 609 return dalvikPrivateDirty + getOtherPrivate(OTHER_ART); 610 } 611 612 /** 613 * Pss of Native Heap bytes in KB due to the application. 614 * Notes: 615 * * Includes private dirty malloc space. 616 * * We don't include nativePrivateClean, because there should be no 617 * such thing as private clean for the Native Heap. 618 * @hide 619 */ getSummaryNativeHeap()620 public int getSummaryNativeHeap() { 621 return nativePrivateDirty; 622 } 623 624 /** 625 * Pss of code and other static resource bytes in KB due to 626 * the application. 627 * @hide 628 */ getSummaryCode()629 public int getSummaryCode() { 630 return getOtherPrivate(OTHER_SO) 631 + getOtherPrivate(OTHER_JAR) 632 + getOtherPrivate(OTHER_APK) 633 + getOtherPrivate(OTHER_TTF) 634 + getOtherPrivate(OTHER_DEX) 635 + getOtherPrivate(OTHER_OAT); 636 } 637 638 /** 639 * Pss in KB of the stack due to the application. 640 * Notes: 641 * * Includes private dirty stack, which includes both Java and Native 642 * stack. 643 * * Does not include private clean stack, because there should be no 644 * such thing as private clean for the stack. 645 * @hide 646 */ getSummaryStack()647 public int getSummaryStack() { 648 return getOtherPrivateDirty(OTHER_STACK); 649 } 650 651 /** 652 * Pss in KB of graphics due to the application. 653 * Notes: 654 * * Includes private Gfx, EGL, and GL. 655 * * Warning: These numbers can be misreported by the graphics drivers. 656 * * We don't include shared graphics. It may make sense to, because 657 * shared graphics are likely buffers due to the application 658 * anyway, but it's simpler to implement to just group all shared 659 * memory into the System category. 660 * @hide 661 */ getSummaryGraphics()662 public int getSummaryGraphics() { 663 return getOtherPrivate(OTHER_GL_DEV) 664 + getOtherPrivate(OTHER_GRAPHICS) 665 + getOtherPrivate(OTHER_GL); 666 } 667 668 /** 669 * Pss in KB due to the application that haven't otherwise been 670 * accounted for. 671 * @hide 672 */ getSummaryPrivateOther()673 public int getSummaryPrivateOther() { 674 return getTotalPrivateClean() 675 + getTotalPrivateDirty() 676 - getSummaryJavaHeap() 677 - getSummaryNativeHeap() 678 - getSummaryCode() 679 - getSummaryStack() 680 - getSummaryGraphics(); 681 } 682 683 /** 684 * Pss in KB due to the system. 685 * Notes: 686 * * Includes all shared memory. 687 * @hide 688 */ getSummarySystem()689 public int getSummarySystem() { 690 return getTotalPss() 691 - getTotalPrivateClean() 692 - getTotalPrivateDirty(); 693 } 694 695 /** 696 * Total Pss in KB. 697 * @hide 698 */ getSummaryTotalPss()699 public int getSummaryTotalPss() { 700 return getTotalPss(); 701 } 702 703 /** 704 * Total Swap in KB. 705 * Notes: 706 * * Some of this memory belongs in other categories, but we don't 707 * know if the Swap memory is shared or private, so we don't know 708 * what to blame on the application and what on the system. 709 * For now, just lump all the Swap in one place. 710 * For kernels reporting SwapPss {@link #getSummaryTotalSwapPss()} 711 * will report the application proportional Swap. 712 * @hide 713 */ getSummaryTotalSwap()714 public int getSummaryTotalSwap() { 715 return getTotalSwappedOut(); 716 } 717 718 /** 719 * Total proportional Swap in KB. 720 * Notes: 721 * * Always 0 if {@link #hasSwappedOutPss} is false. 722 * @hide 723 */ getSummaryTotalSwapPss()724 public int getSummaryTotalSwapPss() { 725 return getTotalSwappedOutPss(); 726 } 727 728 /** 729 * Return true if the kernel is reporting pss swapped out... that is, if 730 * {@link #getSummaryTotalSwapPss()} will return non-0 values. 731 * @hide 732 */ hasSwappedOutPss()733 public boolean hasSwappedOutPss() { 734 return hasSwappedOutPss; 735 } 736 describeContents()737 public int describeContents() { 738 return 0; 739 } 740 writeToParcel(Parcel dest, int flags)741 public void writeToParcel(Parcel dest, int flags) { 742 dest.writeInt(dalvikPss); 743 dest.writeInt(dalvikSwappablePss); 744 dest.writeInt(dalvikPrivateDirty); 745 dest.writeInt(dalvikSharedDirty); 746 dest.writeInt(dalvikPrivateClean); 747 dest.writeInt(dalvikSharedClean); 748 dest.writeInt(dalvikSwappedOut); 749 dest.writeInt(dalvikSwappedOutPss); 750 dest.writeInt(nativePss); 751 dest.writeInt(nativeSwappablePss); 752 dest.writeInt(nativePrivateDirty); 753 dest.writeInt(nativeSharedDirty); 754 dest.writeInt(nativePrivateClean); 755 dest.writeInt(nativeSharedClean); 756 dest.writeInt(nativeSwappedOut); 757 dest.writeInt(nativeSwappedOutPss); 758 dest.writeInt(otherPss); 759 dest.writeInt(otherSwappablePss); 760 dest.writeInt(otherPrivateDirty); 761 dest.writeInt(otherSharedDirty); 762 dest.writeInt(otherPrivateClean); 763 dest.writeInt(otherSharedClean); 764 dest.writeInt(otherSwappedOut); 765 dest.writeInt(hasSwappedOutPss ? 1 : 0); 766 dest.writeInt(otherSwappedOutPss); 767 dest.writeIntArray(otherStats); 768 } 769 readFromParcel(Parcel source)770 public void readFromParcel(Parcel source) { 771 dalvikPss = source.readInt(); 772 dalvikSwappablePss = source.readInt(); 773 dalvikPrivateDirty = source.readInt(); 774 dalvikSharedDirty = source.readInt(); 775 dalvikPrivateClean = source.readInt(); 776 dalvikSharedClean = source.readInt(); 777 dalvikSwappedOut = source.readInt(); 778 dalvikSwappedOutPss = source.readInt(); 779 nativePss = source.readInt(); 780 nativeSwappablePss = source.readInt(); 781 nativePrivateDirty = source.readInt(); 782 nativeSharedDirty = source.readInt(); 783 nativePrivateClean = source.readInt(); 784 nativeSharedClean = source.readInt(); 785 nativeSwappedOut = source.readInt(); 786 nativeSwappedOutPss = source.readInt(); 787 otherPss = source.readInt(); 788 otherSwappablePss = source.readInt(); 789 otherPrivateDirty = source.readInt(); 790 otherSharedDirty = source.readInt(); 791 otherPrivateClean = source.readInt(); 792 otherSharedClean = source.readInt(); 793 otherSwappedOut = source.readInt(); 794 hasSwappedOutPss = source.readInt() != 0; 795 otherSwappedOutPss = source.readInt(); 796 otherStats = source.createIntArray(); 797 } 798 799 public static final Creator<MemoryInfo> CREATOR = new Creator<MemoryInfo>() { 800 public MemoryInfo createFromParcel(Parcel source) { 801 return new MemoryInfo(source); 802 } 803 public MemoryInfo[] newArray(int size) { 804 return new MemoryInfo[size]; 805 } 806 }; 807 MemoryInfo(Parcel source)808 private MemoryInfo(Parcel source) { 809 readFromParcel(source); 810 } 811 } 812 813 814 /** 815 * Wait until a debugger attaches. As soon as the debugger attaches, 816 * this returns, so you will need to place a breakpoint after the 817 * waitForDebugger() call if you want to start tracing immediately. 818 */ waitForDebugger()819 public static void waitForDebugger() { 820 if (!VMDebug.isDebuggingEnabled()) { 821 //System.out.println("debugging not enabled, not waiting"); 822 return; 823 } 824 if (isDebuggerConnected()) 825 return; 826 827 // if DDMS is listening, inform them of our plight 828 System.out.println("Sending WAIT chunk"); 829 byte[] data = new byte[] { 0 }; // 0 == "waiting for debugger" 830 Chunk waitChunk = new Chunk(ChunkHandler.type("WAIT"), data, 0, 1); 831 DdmServer.sendChunk(waitChunk); 832 833 mWaiting = true; 834 while (!isDebuggerConnected()) { 835 try { Thread.sleep(SPIN_DELAY); } 836 catch (InterruptedException ie) {} 837 } 838 mWaiting = false; 839 840 System.out.println("Debugger has connected"); 841 842 /* 843 * There is no "ready to go" signal from the debugger, and we're 844 * not allowed to suspend ourselves -- the debugger expects us to 845 * be running happily, and gets confused if we aren't. We need to 846 * allow the debugger a chance to set breakpoints before we start 847 * running again. 848 * 849 * Sit and spin until the debugger has been idle for a short while. 850 */ 851 while (true) { 852 long delta = VMDebug.lastDebuggerActivity(); 853 if (delta < 0) { 854 System.out.println("debugger detached?"); 855 break; 856 } 857 858 if (delta < MIN_DEBUGGER_IDLE) { 859 System.out.println("waiting for debugger to settle..."); 860 try { Thread.sleep(SPIN_DELAY); } 861 catch (InterruptedException ie) {} 862 } else { 863 System.out.println("debugger has settled (" + delta + ")"); 864 break; 865 } 866 } 867 } 868 869 /** 870 * Returns "true" if one or more threads is waiting for a debugger 871 * to attach. 872 */ waitingForDebugger()873 public static boolean waitingForDebugger() { 874 return mWaiting; 875 } 876 877 /** 878 * Determine if a debugger is currently attached. 879 */ isDebuggerConnected()880 public static boolean isDebuggerConnected() { 881 return VMDebug.isDebuggerConnected(); 882 } 883 884 /** 885 * Returns an array of strings that identify VM features. This is 886 * used by DDMS to determine what sorts of operations the VM can 887 * perform. 888 * 889 * @hide 890 */ getVmFeatureList()891 public static String[] getVmFeatureList() { 892 return VMDebug.getVmFeatureList(); 893 } 894 895 /** 896 * Change the JDWP port. 897 * 898 * @deprecated no longer needed or useful 899 */ 900 @Deprecated changeDebugPort(int port)901 public static void changeDebugPort(int port) {} 902 903 /** 904 * This is the pathname to the sysfs file that enables and disables 905 * tracing on the qemu emulator. 906 */ 907 private static final String SYSFS_QEMU_TRACE_STATE = "/sys/qemu_trace/state"; 908 909 /** 910 * Enable qemu tracing. For this to work requires running everything inside 911 * the qemu emulator; otherwise, this method will have no effect. The trace 912 * file is specified on the command line when the emulator is started. For 913 * example, the following command line <br /> 914 * <code>emulator -trace foo</code><br /> 915 * will start running the emulator and create a trace file named "foo". This 916 * method simply enables writing the trace records to the trace file. 917 * 918 * <p> 919 * The main differences between this and {@link #startMethodTracing()} are 920 * that tracing in the qemu emulator traces every cpu instruction of every 921 * process, including kernel code, so we have more complete information, 922 * including all context switches. We can also get more detailed information 923 * such as cache misses. The sequence of calls is determined by 924 * post-processing the instruction trace. The qemu tracing is also done 925 * without modifying the application or perturbing the timing of calls 926 * because no instrumentation is added to the application being traced. 927 * </p> 928 * 929 * <p> 930 * One limitation of using this method compared to using 931 * {@link #startMethodTracing()} on the real device is that the emulator 932 * does not model all of the real hardware effects such as memory and 933 * bus contention. The emulator also has a simple cache model and cannot 934 * capture all the complexities of a real cache. 935 * </p> 936 */ startNativeTracing()937 public static void startNativeTracing() { 938 // Open the sysfs file for writing and write "1" to it. 939 PrintWriter outStream = null; 940 try { 941 FileOutputStream fos = new FileOutputStream(SYSFS_QEMU_TRACE_STATE); 942 outStream = new FastPrintWriter(fos); 943 outStream.println("1"); 944 } catch (Exception e) { 945 } finally { 946 if (outStream != null) 947 outStream.close(); 948 } 949 950 VMDebug.startEmulatorTracing(); 951 } 952 953 /** 954 * Stop qemu tracing. See {@link #startNativeTracing()} to start tracing. 955 * 956 * <p>Tracing can be started and stopped as many times as desired. When 957 * the qemu emulator itself is stopped then the buffered trace records 958 * are flushed and written to the trace file. In fact, it is not necessary 959 * to call this method at all; simply killing qemu is sufficient. But 960 * starting and stopping a trace is useful for examining a specific 961 * region of code.</p> 962 */ stopNativeTracing()963 public static void stopNativeTracing() { 964 VMDebug.stopEmulatorTracing(); 965 966 // Open the sysfs file for writing and write "0" to it. 967 PrintWriter outStream = null; 968 try { 969 FileOutputStream fos = new FileOutputStream(SYSFS_QEMU_TRACE_STATE); 970 outStream = new FastPrintWriter(fos); 971 outStream.println("0"); 972 } catch (Exception e) { 973 // We could print an error message here but we probably want 974 // to quietly ignore errors if we are not running in the emulator. 975 } finally { 976 if (outStream != null) 977 outStream.close(); 978 } 979 } 980 981 /** 982 * Enable "emulator traces", in which information about the current 983 * method is made available to the "emulator -trace" feature. There 984 * is no corresponding "disable" call -- this is intended for use by 985 * the framework when tracing should be turned on and left that way, so 986 * that traces captured with F9/F10 will include the necessary data. 987 * 988 * This puts the VM into "profile" mode, which has performance 989 * consequences. 990 * 991 * To temporarily enable tracing, use {@link #startNativeTracing()}. 992 */ enableEmulatorTraceOutput()993 public static void enableEmulatorTraceOutput() { 994 VMDebug.startEmulatorTracing(); 995 } 996 997 /** 998 * Start method tracing with default log name and buffer size. 999 * <p> 1000 * By default, the trace file is called "dmtrace.trace" and it's placed 1001 * under your package-specific directory on primary shared/external storage, 1002 * as returned by {@link Context#getExternalFilesDir(String)}. 1003 * <p> 1004 * See <a href="{@docRoot}guide/developing/tools/traceview.html">Traceview: 1005 * A Graphical Log Viewer</a> for information about reading trace files. 1006 * <p class="note"> 1007 * When method tracing is enabled, the VM will run more slowly than usual, 1008 * so the timings from the trace files should only be considered in relative 1009 * terms (e.g. was run #1 faster than run #2). The times for native methods 1010 * will not change, so don't try to use this to compare the performance of 1011 * interpreted and native implementations of the same method. As an 1012 * alternative, consider using sampling-based method tracing via 1013 * {@link #startMethodTracingSampling(String, int, int)} or "native" tracing 1014 * in the emulator via {@link #startNativeTracing()}. 1015 * </p> 1016 */ startMethodTracing()1017 public static void startMethodTracing() { 1018 VMDebug.startMethodTracing(fixTracePath(null), 0, 0, false, 0); 1019 } 1020 1021 /** 1022 * Start method tracing, specifying the trace log file path. 1023 * <p> 1024 * When a relative file path is given, the trace file will be placed under 1025 * your package-specific directory on primary shared/external storage, as 1026 * returned by {@link Context#getExternalFilesDir(String)}. 1027 * <p> 1028 * See <a href="{@docRoot}guide/developing/tools/traceview.html">Traceview: 1029 * A Graphical Log Viewer</a> for information about reading trace files. 1030 * <p class="note"> 1031 * When method tracing is enabled, the VM will run more slowly than usual, 1032 * so the timings from the trace files should only be considered in relative 1033 * terms (e.g. was run #1 faster than run #2). The times for native methods 1034 * will not change, so don't try to use this to compare the performance of 1035 * interpreted and native implementations of the same method. As an 1036 * alternative, consider using sampling-based method tracing via 1037 * {@link #startMethodTracingSampling(String, int, int)} or "native" tracing 1038 * in the emulator via {@link #startNativeTracing()}. 1039 * </p> 1040 * 1041 * @param tracePath Path to the trace log file to create. If {@code null}, 1042 * this will default to "dmtrace.trace". If the file already 1043 * exists, it will be truncated. If the path given does not end 1044 * in ".trace", it will be appended for you. 1045 */ startMethodTracing(String tracePath)1046 public static void startMethodTracing(String tracePath) { 1047 startMethodTracing(tracePath, 0, 0); 1048 } 1049 1050 /** 1051 * Start method tracing, specifying the trace log file name and the buffer 1052 * size. 1053 * <p> 1054 * When a relative file path is given, the trace file will be placed under 1055 * your package-specific directory on primary shared/external storage, as 1056 * returned by {@link Context#getExternalFilesDir(String)}. 1057 * <p> 1058 * See <a href="{@docRoot}guide/developing/tools/traceview.html">Traceview: 1059 * A Graphical Log Viewer</a> for information about reading trace files. 1060 * <p class="note"> 1061 * When method tracing is enabled, the VM will run more slowly than usual, 1062 * so the timings from the trace files should only be considered in relative 1063 * terms (e.g. was run #1 faster than run #2). The times for native methods 1064 * will not change, so don't try to use this to compare the performance of 1065 * interpreted and native implementations of the same method. As an 1066 * alternative, consider using sampling-based method tracing via 1067 * {@link #startMethodTracingSampling(String, int, int)} or "native" tracing 1068 * in the emulator via {@link #startNativeTracing()}. 1069 * </p> 1070 * 1071 * @param tracePath Path to the trace log file to create. If {@code null}, 1072 * this will default to "dmtrace.trace". If the file already 1073 * exists, it will be truncated. If the path given does not end 1074 * in ".trace", it will be appended for you. 1075 * @param bufferSize The maximum amount of trace data we gather. If not 1076 * given, it defaults to 8MB. 1077 */ startMethodTracing(String tracePath, int bufferSize)1078 public static void startMethodTracing(String tracePath, int bufferSize) { 1079 startMethodTracing(tracePath, bufferSize, 0); 1080 } 1081 1082 /** 1083 * Start method tracing, specifying the trace log file name, the buffer 1084 * size, and flags. 1085 * <p> 1086 * When a relative file path is given, the trace file will be placed under 1087 * your package-specific directory on primary shared/external storage, as 1088 * returned by {@link Context#getExternalFilesDir(String)}. 1089 * <p> 1090 * See <a href="{@docRoot}guide/developing/tools/traceview.html">Traceview: 1091 * A Graphical Log Viewer</a> for information about reading trace files. 1092 * <p class="note"> 1093 * When method tracing is enabled, the VM will run more slowly than usual, 1094 * so the timings from the trace files should only be considered in relative 1095 * terms (e.g. was run #1 faster than run #2). The times for native methods 1096 * will not change, so don't try to use this to compare the performance of 1097 * interpreted and native implementations of the same method. As an 1098 * alternative, consider using sampling-based method tracing via 1099 * {@link #startMethodTracingSampling(String, int, int)} or "native" tracing 1100 * in the emulator via {@link #startNativeTracing()}. 1101 * </p> 1102 * 1103 * @param tracePath Path to the trace log file to create. If {@code null}, 1104 * this will default to "dmtrace.trace". If the file already 1105 * exists, it will be truncated. If the path given does not end 1106 * in ".trace", it will be appended for you. 1107 * @param bufferSize The maximum amount of trace data we gather. If not 1108 * given, it defaults to 8MB. 1109 * @param flags Flags to control method tracing. The only one that is 1110 * currently defined is {@link #TRACE_COUNT_ALLOCS}. 1111 */ startMethodTracing(String tracePath, int bufferSize, int flags)1112 public static void startMethodTracing(String tracePath, int bufferSize, int flags) { 1113 VMDebug.startMethodTracing(fixTracePath(tracePath), bufferSize, flags, false, 0); 1114 } 1115 1116 /** 1117 * Start sampling-based method tracing, specifying the trace log file name, 1118 * the buffer size, and the sampling interval. 1119 * <p> 1120 * When a relative file path is given, the trace file will be placed under 1121 * your package-specific directory on primary shared/external storage, as 1122 * returned by {@link Context#getExternalFilesDir(String)}. 1123 * <p> 1124 * See <a href="{@docRoot}guide/developing/tools/traceview.html">Traceview: 1125 * A Graphical Log Viewer</a> for information about reading trace files. 1126 * 1127 * @param tracePath Path to the trace log file to create. If {@code null}, 1128 * this will default to "dmtrace.trace". If the file already 1129 * exists, it will be truncated. If the path given does not end 1130 * in ".trace", it will be appended for you. 1131 * @param bufferSize The maximum amount of trace data we gather. If not 1132 * given, it defaults to 8MB. 1133 * @param intervalUs The amount of time between each sample in microseconds. 1134 */ startMethodTracingSampling(String tracePath, int bufferSize, int intervalUs)1135 public static void startMethodTracingSampling(String tracePath, int bufferSize, 1136 int intervalUs) { 1137 VMDebug.startMethodTracing(fixTracePath(tracePath), bufferSize, 0, true, intervalUs); 1138 } 1139 1140 /** 1141 * Formats name of trace log file for method tracing. 1142 */ fixTracePath(String tracePath)1143 private static String fixTracePath(String tracePath) { 1144 if (tracePath == null || tracePath.charAt(0) != '/') { 1145 final Context context = AppGlobals.getInitialApplication(); 1146 final File dir; 1147 if (context != null) { 1148 dir = context.getExternalFilesDir(null); 1149 } else { 1150 dir = Environment.getExternalStorageDirectory(); 1151 } 1152 1153 if (tracePath == null) { 1154 tracePath = new File(dir, DEFAULT_TRACE_BODY).getAbsolutePath(); 1155 } else { 1156 tracePath = new File(dir, tracePath).getAbsolutePath(); 1157 } 1158 } 1159 if (!tracePath.endsWith(DEFAULT_TRACE_EXTENSION)) { 1160 tracePath += DEFAULT_TRACE_EXTENSION; 1161 } 1162 return tracePath; 1163 } 1164 1165 /** 1166 * Like startMethodTracing(String, int, int), but taking an already-opened 1167 * FileDescriptor in which the trace is written. The file name is also 1168 * supplied simply for logging. Makes a dup of the file descriptor. 1169 * 1170 * Not exposed in the SDK unless we are really comfortable with supporting 1171 * this and find it would be useful. 1172 * @hide 1173 */ startMethodTracing(String traceName, FileDescriptor fd, int bufferSize, int flags, boolean streamOutput)1174 public static void startMethodTracing(String traceName, FileDescriptor fd, 1175 int bufferSize, int flags, boolean streamOutput) { 1176 VMDebug.startMethodTracing(traceName, fd, bufferSize, flags, false, 0, streamOutput); 1177 } 1178 1179 /** 1180 * Starts method tracing without a backing file. When stopMethodTracing 1181 * is called, the result is sent directly to DDMS. (If DDMS is not 1182 * attached when tracing ends, the profiling data will be discarded.) 1183 * 1184 * @hide 1185 */ startMethodTracingDdms(int bufferSize, int flags, boolean samplingEnabled, int intervalUs)1186 public static void startMethodTracingDdms(int bufferSize, int flags, 1187 boolean samplingEnabled, int intervalUs) { 1188 VMDebug.startMethodTracingDdms(bufferSize, flags, samplingEnabled, intervalUs); 1189 } 1190 1191 /** 1192 * Determine whether method tracing is currently active and what type is 1193 * active. 1194 * 1195 * @hide 1196 */ getMethodTracingMode()1197 public static int getMethodTracingMode() { 1198 return VMDebug.getMethodTracingMode(); 1199 } 1200 1201 /** 1202 * Stop method tracing. 1203 */ stopMethodTracing()1204 public static void stopMethodTracing() { 1205 VMDebug.stopMethodTracing(); 1206 } 1207 1208 /** 1209 * Get an indication of thread CPU usage. The value returned 1210 * indicates the amount of time that the current thread has spent 1211 * executing code or waiting for certain types of I/O. 1212 * 1213 * The time is expressed in nanoseconds, and is only meaningful 1214 * when compared to the result from an earlier call. Note that 1215 * nanosecond resolution does not imply nanosecond accuracy. 1216 * 1217 * On system which don't support this operation, the call returns -1. 1218 */ threadCpuTimeNanos()1219 public static long threadCpuTimeNanos() { 1220 return VMDebug.threadCpuTimeNanos(); 1221 } 1222 1223 /** 1224 * Start counting the number and aggregate size of memory allocations. 1225 * 1226 * <p>The {@link #startAllocCounting() start} method resets the counts and enables counting. 1227 * The {@link #stopAllocCounting() stop} method disables the counting so that the analysis 1228 * code doesn't cause additional allocations. The various <code>get</code> methods return 1229 * the specified value. And the various <code>reset</code> methods reset the specified 1230 * count.</p> 1231 * 1232 * <p>Counts are kept for the system as a whole (global) and for each thread. 1233 * The per-thread counts for threads other than the current thread 1234 * are not cleared by the "reset" or "start" calls.</p> 1235 * 1236 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1237 */ 1238 @Deprecated startAllocCounting()1239 public static void startAllocCounting() { 1240 VMDebug.startAllocCounting(); 1241 } 1242 1243 /** 1244 * Stop counting the number and aggregate size of memory allocations. 1245 * 1246 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1247 */ 1248 @Deprecated stopAllocCounting()1249 public static void stopAllocCounting() { 1250 VMDebug.stopAllocCounting(); 1251 } 1252 1253 /** 1254 * Returns the global count of objects allocated by the runtime between a 1255 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1256 * 1257 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1258 */ 1259 @Deprecated getGlobalAllocCount()1260 public static int getGlobalAllocCount() { 1261 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_OBJECTS); 1262 } 1263 1264 /** 1265 * Clears the global count of objects allocated. 1266 * @see #getGlobalAllocCount() 1267 * 1268 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1269 */ 1270 @Deprecated resetGlobalAllocCount()1271 public static void resetGlobalAllocCount() { 1272 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_OBJECTS); 1273 } 1274 1275 /** 1276 * Returns the global size, in bytes, of objects allocated by the runtime between a 1277 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1278 * 1279 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1280 */ 1281 @Deprecated getGlobalAllocSize()1282 public static int getGlobalAllocSize() { 1283 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_BYTES); 1284 } 1285 1286 /** 1287 * Clears the global size of objects allocated. 1288 * @see #getGlobalAllocSize() 1289 * 1290 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1291 */ 1292 @Deprecated resetGlobalAllocSize()1293 public static void resetGlobalAllocSize() { 1294 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_BYTES); 1295 } 1296 1297 /** 1298 * Returns the global count of objects freed by the runtime between a 1299 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1300 * 1301 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1302 */ 1303 @Deprecated getGlobalFreedCount()1304 public static int getGlobalFreedCount() { 1305 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_FREED_OBJECTS); 1306 } 1307 1308 /** 1309 * Clears the global count of objects freed. 1310 * @see #getGlobalFreedCount() 1311 * 1312 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1313 */ 1314 @Deprecated resetGlobalFreedCount()1315 public static void resetGlobalFreedCount() { 1316 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_FREED_OBJECTS); 1317 } 1318 1319 /** 1320 * Returns the global size, in bytes, of objects freed by the runtime between a 1321 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1322 * 1323 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1324 */ 1325 @Deprecated getGlobalFreedSize()1326 public static int getGlobalFreedSize() { 1327 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_FREED_BYTES); 1328 } 1329 1330 /** 1331 * Clears the global size of objects freed. 1332 * @see #getGlobalFreedSize() 1333 * 1334 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1335 */ 1336 @Deprecated resetGlobalFreedSize()1337 public static void resetGlobalFreedSize() { 1338 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_FREED_BYTES); 1339 } 1340 1341 /** 1342 * Returns the number of non-concurrent GC invocations between a 1343 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1344 * 1345 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1346 */ 1347 @Deprecated getGlobalGcInvocationCount()1348 public static int getGlobalGcInvocationCount() { 1349 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_GC_INVOCATIONS); 1350 } 1351 1352 /** 1353 * Clears the count of non-concurrent GC invocations. 1354 * @see #getGlobalGcInvocationCount() 1355 * 1356 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1357 */ 1358 @Deprecated resetGlobalGcInvocationCount()1359 public static void resetGlobalGcInvocationCount() { 1360 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_GC_INVOCATIONS); 1361 } 1362 1363 /** 1364 * Returns the number of classes successfully initialized (ie those that executed without 1365 * throwing an exception) between a {@link #startAllocCounting() start} and 1366 * {@link #stopAllocCounting() stop}. 1367 * 1368 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1369 */ 1370 @Deprecated getGlobalClassInitCount()1371 public static int getGlobalClassInitCount() { 1372 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_COUNT); 1373 } 1374 1375 /** 1376 * Clears the count of classes initialized. 1377 * @see #getGlobalClassInitCount() 1378 * 1379 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1380 */ 1381 @Deprecated resetGlobalClassInitCount()1382 public static void resetGlobalClassInitCount() { 1383 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_COUNT); 1384 } 1385 1386 /** 1387 * Returns the time spent successfully initializing classes between a 1388 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1389 * 1390 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1391 */ 1392 @Deprecated getGlobalClassInitTime()1393 public static int getGlobalClassInitTime() { 1394 /* cumulative elapsed time for class initialization, in usec */ 1395 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_TIME); 1396 } 1397 1398 /** 1399 * Clears the count of time spent initializing classes. 1400 * @see #getGlobalClassInitTime() 1401 * 1402 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1403 */ 1404 @Deprecated resetGlobalClassInitTime()1405 public static void resetGlobalClassInitTime() { 1406 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_TIME); 1407 } 1408 1409 /** 1410 * This method exists for compatibility and always returns 0. 1411 * @deprecated This method is now obsolete. 1412 */ 1413 @Deprecated getGlobalExternalAllocCount()1414 public static int getGlobalExternalAllocCount() { 1415 return 0; 1416 } 1417 1418 /** 1419 * This method exists for compatibility and has no effect. 1420 * @deprecated This method is now obsolete. 1421 */ 1422 @Deprecated resetGlobalExternalAllocSize()1423 public static void resetGlobalExternalAllocSize() {} 1424 1425 /** 1426 * This method exists for compatibility and has no effect. 1427 * @deprecated This method is now obsolete. 1428 */ 1429 @Deprecated resetGlobalExternalAllocCount()1430 public static void resetGlobalExternalAllocCount() {} 1431 1432 /** 1433 * This method exists for compatibility and always returns 0. 1434 * @deprecated This method is now obsolete. 1435 */ 1436 @Deprecated getGlobalExternalAllocSize()1437 public static int getGlobalExternalAllocSize() { 1438 return 0; 1439 } 1440 1441 /** 1442 * This method exists for compatibility and always returns 0. 1443 * @deprecated This method is now obsolete. 1444 */ 1445 @Deprecated getGlobalExternalFreedCount()1446 public static int getGlobalExternalFreedCount() { 1447 return 0; 1448 } 1449 1450 /** 1451 * This method exists for compatibility and has no effect. 1452 * @deprecated This method is now obsolete. 1453 */ 1454 @Deprecated resetGlobalExternalFreedCount()1455 public static void resetGlobalExternalFreedCount() {} 1456 1457 /** 1458 * This method exists for compatibility and has no effect. 1459 * @deprecated This method is now obsolete. 1460 */ 1461 @Deprecated getGlobalExternalFreedSize()1462 public static int getGlobalExternalFreedSize() { 1463 return 0; 1464 } 1465 1466 /** 1467 * This method exists for compatibility and has no effect. 1468 * @deprecated This method is now obsolete. 1469 */ 1470 @Deprecated resetGlobalExternalFreedSize()1471 public static void resetGlobalExternalFreedSize() {} 1472 1473 /** 1474 * Returns the thread-local count of objects allocated by the runtime between a 1475 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1476 * 1477 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1478 */ 1479 @Deprecated getThreadAllocCount()1480 public static int getThreadAllocCount() { 1481 return VMDebug.getAllocCount(VMDebug.KIND_THREAD_ALLOCATED_OBJECTS); 1482 } 1483 1484 /** 1485 * Clears the thread-local count of objects allocated. 1486 * @see #getThreadAllocCount() 1487 * 1488 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1489 */ 1490 @Deprecated resetThreadAllocCount()1491 public static void resetThreadAllocCount() { 1492 VMDebug.resetAllocCount(VMDebug.KIND_THREAD_ALLOCATED_OBJECTS); 1493 } 1494 1495 /** 1496 * Returns the thread-local size of objects allocated by the runtime between a 1497 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1498 * @return The allocated size in bytes. 1499 * 1500 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1501 */ 1502 @Deprecated getThreadAllocSize()1503 public static int getThreadAllocSize() { 1504 return VMDebug.getAllocCount(VMDebug.KIND_THREAD_ALLOCATED_BYTES); 1505 } 1506 1507 /** 1508 * Clears the thread-local count of objects allocated. 1509 * @see #getThreadAllocSize() 1510 * 1511 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1512 */ 1513 @Deprecated resetThreadAllocSize()1514 public static void resetThreadAllocSize() { 1515 VMDebug.resetAllocCount(VMDebug.KIND_THREAD_ALLOCATED_BYTES); 1516 } 1517 1518 /** 1519 * This method exists for compatibility and has no effect. 1520 * @deprecated This method is now obsolete. 1521 */ 1522 @Deprecated getThreadExternalAllocCount()1523 public static int getThreadExternalAllocCount() { 1524 return 0; 1525 } 1526 1527 /** 1528 * This method exists for compatibility and has no effect. 1529 * @deprecated This method is now obsolete. 1530 */ 1531 @Deprecated resetThreadExternalAllocCount()1532 public static void resetThreadExternalAllocCount() {} 1533 1534 /** 1535 * This method exists for compatibility and has no effect. 1536 * @deprecated This method is now obsolete. 1537 */ 1538 @Deprecated getThreadExternalAllocSize()1539 public static int getThreadExternalAllocSize() { 1540 return 0; 1541 } 1542 1543 /** 1544 * This method exists for compatibility and has no effect. 1545 * @deprecated This method is now obsolete. 1546 */ 1547 @Deprecated resetThreadExternalAllocSize()1548 public static void resetThreadExternalAllocSize() {} 1549 1550 /** 1551 * Returns the number of thread-local non-concurrent GC invocations between a 1552 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1553 * 1554 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1555 */ 1556 @Deprecated getThreadGcInvocationCount()1557 public static int getThreadGcInvocationCount() { 1558 return VMDebug.getAllocCount(VMDebug.KIND_THREAD_GC_INVOCATIONS); 1559 } 1560 1561 /** 1562 * Clears the thread-local count of non-concurrent GC invocations. 1563 * @see #getThreadGcInvocationCount() 1564 * 1565 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1566 */ 1567 @Deprecated resetThreadGcInvocationCount()1568 public static void resetThreadGcInvocationCount() { 1569 VMDebug.resetAllocCount(VMDebug.KIND_THREAD_GC_INVOCATIONS); 1570 } 1571 1572 /** 1573 * Clears all the global and thread-local memory allocation counters. 1574 * @see #startAllocCounting() 1575 * 1576 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1577 */ 1578 @Deprecated resetAllCounts()1579 public static void resetAllCounts() { 1580 VMDebug.resetAllocCount(VMDebug.KIND_ALL_COUNTS); 1581 } 1582 1583 /** 1584 * Returns the value of a particular runtime statistic or {@code null} if no 1585 * such runtime statistic exists. 1586 * 1587 * <p>The following table lists the runtime statistics that the runtime supports. 1588 * Note runtime statistics may be added or removed in a future API level.</p> 1589 * 1590 * <table> 1591 * <thead> 1592 * <tr> 1593 * <th>Runtime statistic name</th> 1594 * <th>Meaning</th> 1595 * <th>Example</th> 1596 * <th>Supported (API Levels)</th> 1597 * </tr> 1598 * </thead> 1599 * <tbody> 1600 * <tr> 1601 * <td>art.gc.gc-count</td> 1602 * <td>The number of garbage collection runs.</td> 1603 * <td>{@code 164}</td> 1604 * <td>23</td> 1605 * </tr> 1606 * <tr> 1607 * <td>art.gc.gc-time</td> 1608 * <td>The total duration of garbage collection runs in ms.</td> 1609 * <td>{@code 62364}</td> 1610 * <td>23</td> 1611 * </tr> 1612 * <tr> 1613 * <td>art.gc.bytes-allocated</td> 1614 * <td>The total number of bytes that the application allocated.</td> 1615 * <td>{@code 1463948408}</td> 1616 * <td>23</td> 1617 * </tr> 1618 * <tr> 1619 * <td>art.gc.bytes-freed</td> 1620 * <td>The total number of bytes that garbage collection reclaimed.</td> 1621 * <td>{@code 1313493084}</td> 1622 * <td>23</td> 1623 * </tr> 1624 * <tr> 1625 * <td>art.gc.blocking-gc-count</td> 1626 * <td>The number of blocking garbage collection runs.</td> 1627 * <td>{@code 2}</td> 1628 * <td>23</td> 1629 * </tr> 1630 * <tr> 1631 * <td>art.gc.blocking-gc-time</td> 1632 * <td>The total duration of blocking garbage collection runs in ms.</td> 1633 * <td>{@code 804}</td> 1634 * <td>23</td> 1635 * </tr> 1636 * <tr> 1637 * <td>art.gc.gc-count-rate-histogram</td> 1638 * <td>Every 10 seconds, the gc-count-rate is computed as the number of garbage 1639 * collection runs that have occurred over the last 10 1640 * seconds. art.gc.gc-count-rate-histogram is a histogram of the gc-count-rate 1641 * samples taken since the process began. The histogram can be used to identify 1642 * instances of high rates of garbage collection runs. For example, a histogram 1643 * of "0:34503,1:45350,2:11281,3:8088,4:43,5:8" shows that most of the time 1644 * there are between 0 and 2 garbage collection runs every 10 seconds, but there 1645 * were 8 distinct 10-second intervals in which 5 garbage collection runs 1646 * occurred.</td> 1647 * <td>{@code 0:34503,1:45350,2:11281,3:8088,4:43,5:8}</td> 1648 * <td>23</td> 1649 * </tr> 1650 * <tr> 1651 * <td>art.gc.blocking-gc-count-rate-histogram</td> 1652 * <td>Every 10 seconds, the blocking-gc-count-rate is computed as the number of 1653 * blocking garbage collection runs that have occurred over the last 10 1654 * seconds. art.gc.blocking-gc-count-rate-histogram is a histogram of the 1655 * blocking-gc-count-rate samples taken since the process began. The histogram 1656 * can be used to identify instances of high rates of blocking garbage 1657 * collection runs. For example, a histogram of "0:99269,1:1,2:1" shows that 1658 * most of the time there are zero blocking garbage collection runs every 10 1659 * seconds, but there was one 10-second interval in which one blocking garbage 1660 * collection run occurred, and there was one interval in which two blocking 1661 * garbage collection runs occurred.</td> 1662 * <td>{@code 0:99269,1:1,2:1}</td> 1663 * <td>23</td> 1664 * </tr> 1665 * </tbody> 1666 * </table> 1667 * 1668 * @param statName 1669 * the name of the runtime statistic to look up. 1670 * @return the value of the specified runtime statistic or {@code null} if the 1671 * runtime statistic doesn't exist. 1672 */ getRuntimeStat(String statName)1673 public static String getRuntimeStat(String statName) { 1674 return VMDebug.getRuntimeStat(statName); 1675 } 1676 1677 /** 1678 * Returns a map of the names/values of the runtime statistics 1679 * that {@link #getRuntimeStat(String)} supports. 1680 * 1681 * @return a map of the names/values of the supported runtime statistics. 1682 */ getRuntimeStats()1683 public static Map<String, String> getRuntimeStats() { 1684 return VMDebug.getRuntimeStats(); 1685 } 1686 1687 /** 1688 * Returns the size of the native heap. 1689 * @return The size of the native heap in bytes. 1690 */ getNativeHeapSize()1691 public static native long getNativeHeapSize(); 1692 1693 /** 1694 * Returns the amount of allocated memory in the native heap. 1695 * @return The allocated size in bytes. 1696 */ getNativeHeapAllocatedSize()1697 public static native long getNativeHeapAllocatedSize(); 1698 1699 /** 1700 * Returns the amount of free memory in the native heap. 1701 * @return The freed size in bytes. 1702 */ getNativeHeapFreeSize()1703 public static native long getNativeHeapFreeSize(); 1704 1705 /** 1706 * Retrieves information about this processes memory usages. This information is broken down by 1707 * how much is in use by dalvik, the native heap, and everything else. 1708 * 1709 * <p><b>Note:</b> this method directly retrieves memory information for the give process 1710 * from low-level data available to it. It may not be able to retrieve information about 1711 * some protected allocations, such as graphics. If you want to be sure you can see 1712 * all information about allocations by the process, use instead 1713 * {@link android.app.ActivityManager#getProcessMemoryInfo(int[])}.</p> 1714 */ getMemoryInfo(MemoryInfo memoryInfo)1715 public static native void getMemoryInfo(MemoryInfo memoryInfo); 1716 1717 /** 1718 * Note: currently only works when the requested pid has the same UID 1719 * as the caller. 1720 * @hide 1721 */ getMemoryInfo(int pid, MemoryInfo memoryInfo)1722 public static native void getMemoryInfo(int pid, MemoryInfo memoryInfo); 1723 1724 /** 1725 * Retrieves the PSS memory used by the process as given by the 1726 * smaps. 1727 */ getPss()1728 public static native long getPss(); 1729 1730 /** 1731 * Retrieves the PSS memory used by the process as given by the 1732 * smaps. Optionally supply a long array of 2 entries to also 1733 * receive the Uss and SwapPss of the process, and another array to also 1734 * retrieve the separate memtrack size. 1735 * @hide 1736 */ getPss(int pid, long[] outUssSwapPss, long[] outMemtrack)1737 public static native long getPss(int pid, long[] outUssSwapPss, long[] outMemtrack); 1738 1739 /** @hide */ 1740 public static final int MEMINFO_TOTAL = 0; 1741 /** @hide */ 1742 public static final int MEMINFO_FREE = 1; 1743 /** @hide */ 1744 public static final int MEMINFO_BUFFERS = 2; 1745 /** @hide */ 1746 public static final int MEMINFO_CACHED = 3; 1747 /** @hide */ 1748 public static final int MEMINFO_SHMEM = 4; 1749 /** @hide */ 1750 public static final int MEMINFO_SLAB = 5; 1751 /** @hide */ 1752 public static final int MEMINFO_SLAB_RECLAIMABLE = 6; 1753 /** @hide */ 1754 public static final int MEMINFO_SLAB_UNRECLAIMABLE = 7; 1755 /** @hide */ 1756 public static final int MEMINFO_SWAP_TOTAL = 8; 1757 /** @hide */ 1758 public static final int MEMINFO_SWAP_FREE = 9; 1759 /** @hide */ 1760 public static final int MEMINFO_ZRAM_TOTAL = 10; 1761 /** @hide */ 1762 public static final int MEMINFO_MAPPED = 11; 1763 /** @hide */ 1764 public static final int MEMINFO_VM_ALLOC_USED = 12; 1765 /** @hide */ 1766 public static final int MEMINFO_PAGE_TABLES = 13; 1767 /** @hide */ 1768 public static final int MEMINFO_KERNEL_STACK = 14; 1769 /** @hide */ 1770 public static final int MEMINFO_COUNT = 15; 1771 1772 /** 1773 * Retrieves /proc/meminfo. outSizes is filled with fields 1774 * as defined by MEMINFO_* offsets. 1775 * @hide 1776 */ getMemInfo(long[] outSizes)1777 public static native void getMemInfo(long[] outSizes); 1778 1779 /** 1780 * Establish an object allocation limit in the current thread. 1781 * This feature was never enabled in release builds. The 1782 * allocation limits feature was removed in Honeycomb. This 1783 * method exists for compatibility and always returns -1 and has 1784 * no effect. 1785 * 1786 * @deprecated This method is now obsolete. 1787 */ 1788 @Deprecated setAllocationLimit(int limit)1789 public static int setAllocationLimit(int limit) { 1790 return -1; 1791 } 1792 1793 /** 1794 * Establish a global object allocation limit. This feature was 1795 * never enabled in release builds. The allocation limits feature 1796 * was removed in Honeycomb. This method exists for compatibility 1797 * and always returns -1 and has no effect. 1798 * 1799 * @deprecated This method is now obsolete. 1800 */ 1801 @Deprecated setGlobalAllocationLimit(int limit)1802 public static int setGlobalAllocationLimit(int limit) { 1803 return -1; 1804 } 1805 1806 /** 1807 * Dump a list of all currently loaded class to the log file. 1808 * 1809 * @param flags See constants above. 1810 */ printLoadedClasses(int flags)1811 public static void printLoadedClasses(int flags) { 1812 VMDebug.printLoadedClasses(flags); 1813 } 1814 1815 /** 1816 * Get the number of loaded classes. 1817 * @return the number of loaded classes. 1818 */ getLoadedClassCount()1819 public static int getLoadedClassCount() { 1820 return VMDebug.getLoadedClassCount(); 1821 } 1822 1823 /** 1824 * Dump "hprof" data to the specified file. This may cause a GC. 1825 * 1826 * @param fileName Full pathname of output file (e.g. "/sdcard/dump.hprof"). 1827 * @throws UnsupportedOperationException if the VM was built without 1828 * HPROF support. 1829 * @throws IOException if an error occurs while opening or writing files. 1830 */ dumpHprofData(String fileName)1831 public static void dumpHprofData(String fileName) throws IOException { 1832 VMDebug.dumpHprofData(fileName); 1833 } 1834 1835 /** 1836 * Like dumpHprofData(String), but takes an already-opened 1837 * FileDescriptor to which the trace is written. The file name is also 1838 * supplied simply for logging. Makes a dup of the file descriptor. 1839 * 1840 * Primarily for use by the "am" shell command. 1841 * 1842 * @hide 1843 */ dumpHprofData(String fileName, FileDescriptor fd)1844 public static void dumpHprofData(String fileName, FileDescriptor fd) 1845 throws IOException { 1846 VMDebug.dumpHprofData(fileName, fd); 1847 } 1848 1849 /** 1850 * Collect "hprof" and send it to DDMS. This may cause a GC. 1851 * 1852 * @throws UnsupportedOperationException if the VM was built without 1853 * HPROF support. 1854 * @hide 1855 */ dumpHprofDataDdms()1856 public static void dumpHprofDataDdms() { 1857 VMDebug.dumpHprofDataDdms(); 1858 } 1859 1860 /** 1861 * Writes native heap data to the specified file descriptor. 1862 * 1863 * @hide 1864 */ dumpNativeHeap(FileDescriptor fd)1865 public static native void dumpNativeHeap(FileDescriptor fd); 1866 1867 /** 1868 * Writes malloc info data to the specified file descriptor. 1869 * 1870 * @hide 1871 */ dumpNativeMallocInfo(FileDescriptor fd)1872 public static native void dumpNativeMallocInfo(FileDescriptor fd); 1873 1874 /** 1875 * Returns a count of the extant instances of a class. 1876 * 1877 * @hide 1878 */ countInstancesOfClass(Class cls)1879 public static long countInstancesOfClass(Class cls) { 1880 return VMDebug.countInstancesOfClass(cls, true); 1881 } 1882 1883 /** 1884 * Returns the number of sent transactions from this process. 1885 * @return The number of sent transactions or -1 if it could not read t. 1886 */ getBinderSentTransactions()1887 public static native int getBinderSentTransactions(); 1888 1889 /** 1890 * Returns the number of received transactions from the binder driver. 1891 * @return The number of received transactions or -1 if it could not read the stats. 1892 */ getBinderReceivedTransactions()1893 public static native int getBinderReceivedTransactions(); 1894 1895 /** 1896 * Returns the number of active local Binder objects that exist in the 1897 * current process. 1898 */ getBinderLocalObjectCount()1899 public static final native int getBinderLocalObjectCount(); 1900 1901 /** 1902 * Returns the number of references to remote proxy Binder objects that 1903 * exist in the current process. 1904 */ getBinderProxyObjectCount()1905 public static final native int getBinderProxyObjectCount(); 1906 1907 /** 1908 * Returns the number of death notification links to Binder objects that 1909 * exist in the current process. 1910 */ getBinderDeathObjectCount()1911 public static final native int getBinderDeathObjectCount(); 1912 1913 /** 1914 * Primes the register map cache. 1915 * 1916 * Only works for classes in the bootstrap class loader. Does not 1917 * cause classes to be loaded if they're not already present. 1918 * 1919 * The classAndMethodDesc argument is a concatentation of the VM-internal 1920 * class descriptor, method name, and method descriptor. Examples: 1921 * Landroid/os/Looper;.loop:()V 1922 * Landroid/app/ActivityThread;.main:([Ljava/lang/String;)V 1923 * 1924 * @param classAndMethodDesc the method to prepare 1925 * 1926 * @hide 1927 */ cacheRegisterMap(String classAndMethodDesc)1928 public static final boolean cacheRegisterMap(String classAndMethodDesc) { 1929 return VMDebug.cacheRegisterMap(classAndMethodDesc); 1930 } 1931 1932 /** 1933 * Dumps the contents of VM reference tables (e.g. JNI locals and 1934 * globals) to the log file. 1935 * 1936 * @hide 1937 */ dumpReferenceTables()1938 public static final void dumpReferenceTables() { 1939 VMDebug.dumpReferenceTables(); 1940 } 1941 1942 /** 1943 * API for gathering and querying instruction counts. 1944 * 1945 * Example usage: 1946 * <pre> 1947 * Debug.InstructionCount icount = new Debug.InstructionCount(); 1948 * icount.resetAndStart(); 1949 * [... do lots of stuff ...] 1950 * if (icount.collect()) { 1951 * System.out.println("Total instructions executed: " 1952 * + icount.globalTotal()); 1953 * System.out.println("Method invocations: " 1954 * + icount.globalMethodInvocations()); 1955 * } 1956 * </pre> 1957 * 1958 * @deprecated Instruction counting is no longer supported. 1959 */ 1960 @Deprecated 1961 public static class InstructionCount { 1962 private static final int NUM_INSTR = 1963 OpcodeInfo.MAXIMUM_PACKED_VALUE + 1; 1964 1965 private int[] mCounts; 1966 InstructionCount()1967 public InstructionCount() { 1968 mCounts = new int[NUM_INSTR]; 1969 } 1970 1971 /** 1972 * Reset counters and ensure counts are running. Counts may 1973 * have already been running. 1974 * 1975 * @return true if counting was started 1976 */ resetAndStart()1977 public boolean resetAndStart() { 1978 try { 1979 VMDebug.startInstructionCounting(); 1980 VMDebug.resetInstructionCount(); 1981 } catch (UnsupportedOperationException uoe) { 1982 return false; 1983 } 1984 return true; 1985 } 1986 1987 /** 1988 * Collect instruction counts. May or may not stop the 1989 * counting process. 1990 */ collect()1991 public boolean collect() { 1992 try { 1993 VMDebug.stopInstructionCounting(); 1994 VMDebug.getInstructionCount(mCounts); 1995 } catch (UnsupportedOperationException uoe) { 1996 return false; 1997 } 1998 return true; 1999 } 2000 2001 /** 2002 * Return the total number of instructions executed globally (i.e. in 2003 * all threads). 2004 */ globalTotal()2005 public int globalTotal() { 2006 int count = 0; 2007 2008 for (int i = 0; i < NUM_INSTR; i++) { 2009 count += mCounts[i]; 2010 } 2011 2012 return count; 2013 } 2014 2015 /** 2016 * Return the total number of method-invocation instructions 2017 * executed globally. 2018 */ globalMethodInvocations()2019 public int globalMethodInvocations() { 2020 int count = 0; 2021 2022 for (int i = 0; i < NUM_INSTR; i++) { 2023 if (OpcodeInfo.isInvoke(i)) { 2024 count += mCounts[i]; 2025 } 2026 } 2027 2028 return count; 2029 } 2030 } 2031 2032 /** 2033 * A Map of typed debug properties. 2034 */ 2035 private static final TypedProperties debugProperties; 2036 2037 /* 2038 * Load the debug properties from the standard files into debugProperties. 2039 */ 2040 static { 2041 if (false) { 2042 final String TAG = "DebugProperties"; 2043 final String[] files = { "/system/debug.prop", "/debug.prop", "/data/debug.prop" }; 2044 final TypedProperties tp = new TypedProperties(); 2045 2046 // Read the properties from each of the files, if present. 2047 for (String file : files) { 2048 Reader r; 2049 try { 2050 r = new FileReader(file); 2051 } catch (FileNotFoundException ex) { 2052 // It's ok if a file is missing. 2053 continue; 2054 } 2055 2056 try { 2057 tp.load(r); 2058 } catch (Exception ex) { 2059 throw new RuntimeException("Problem loading " + file, ex); 2060 } finally { 2061 try { r.close()2062 r.close(); 2063 } catch (IOException ex) { 2064 // Ignore this error. 2065 } 2066 } 2067 } 2068 2069 debugProperties = tp.isEmpty() ? null : tp; 2070 } else { 2071 debugProperties = null; 2072 } 2073 } 2074 2075 2076 /** 2077 * Returns true if the type of the field matches the specified class. 2078 * Handles the case where the class is, e.g., java.lang.Boolean, but 2079 * the field is of the primitive "boolean" type. Also handles all of 2080 * the java.lang.Number subclasses. 2081 */ fieldTypeMatches(Field field, Class<?> cl)2082 private static boolean fieldTypeMatches(Field field, Class<?> cl) { 2083 Class<?> fieldClass = field.getType(); 2084 if (fieldClass == cl) { 2085 return true; 2086 } 2087 Field primitiveTypeField; 2088 try { 2089 /* All of the classes we care about (Boolean, Integer, etc.) 2090 * have a Class field called "TYPE" that points to the corresponding 2091 * primitive class. 2092 */ 2093 primitiveTypeField = cl.getField("TYPE"); 2094 } catch (NoSuchFieldException ex) { 2095 return false; 2096 } 2097 try { 2098 return fieldClass == (Class<?>) primitiveTypeField.get(null); 2099 } catch (IllegalAccessException ex) { 2100 return false; 2101 } 2102 } 2103 2104 2105 /** 2106 * Looks up the property that corresponds to the field, and sets the field's value 2107 * if the types match. 2108 */ modifyFieldIfSet(final Field field, final TypedProperties properties, final String propertyName)2109 private static void modifyFieldIfSet(final Field field, final TypedProperties properties, 2110 final String propertyName) { 2111 if (field.getType() == java.lang.String.class) { 2112 int stringInfo = properties.getStringInfo(propertyName); 2113 switch (stringInfo) { 2114 case TypedProperties.STRING_SET: 2115 // Handle as usual below. 2116 break; 2117 case TypedProperties.STRING_NULL: 2118 try { 2119 field.set(null, null); // null object for static fields; null string 2120 } catch (IllegalAccessException ex) { 2121 throw new IllegalArgumentException( 2122 "Cannot set field for " + propertyName, ex); 2123 } 2124 return; 2125 case TypedProperties.STRING_NOT_SET: 2126 return; 2127 case TypedProperties.STRING_TYPE_MISMATCH: 2128 throw new IllegalArgumentException( 2129 "Type of " + propertyName + " " + 2130 " does not match field type (" + field.getType() + ")"); 2131 default: 2132 throw new IllegalStateException( 2133 "Unexpected getStringInfo(" + propertyName + ") return value " + 2134 stringInfo); 2135 } 2136 } 2137 Object value = properties.get(propertyName); 2138 if (value != null) { 2139 if (!fieldTypeMatches(field, value.getClass())) { 2140 throw new IllegalArgumentException( 2141 "Type of " + propertyName + " (" + value.getClass() + ") " + 2142 " does not match field type (" + field.getType() + ")"); 2143 } 2144 try { 2145 field.set(null, value); // null object for static fields 2146 } catch (IllegalAccessException ex) { 2147 throw new IllegalArgumentException( 2148 "Cannot set field for " + propertyName, ex); 2149 } 2150 } 2151 } 2152 2153 2154 /** 2155 * Equivalent to <code>setFieldsOn(cl, false)</code>. 2156 * 2157 * @see #setFieldsOn(Class, boolean) 2158 * 2159 * @hide 2160 */ setFieldsOn(Class<?> cl)2161 public static void setFieldsOn(Class<?> cl) { 2162 setFieldsOn(cl, false); 2163 } 2164 2165 /** 2166 * Reflectively sets static fields of a class based on internal debugging 2167 * properties. This method is a no-op if false is 2168 * false. 2169 * <p> 2170 * <strong>NOTE TO APPLICATION DEVELOPERS</strong>: false will 2171 * always be false in release builds. This API is typically only useful 2172 * for platform developers. 2173 * </p> 2174 * Class setup: define a class whose only fields are non-final, static 2175 * primitive types (except for "char") or Strings. In a static block 2176 * after the field definitions/initializations, pass the class to 2177 * this method, Debug.setFieldsOn(). Example: 2178 * <pre> 2179 * package com.example; 2180 * 2181 * import android.os.Debug; 2182 * 2183 * public class MyDebugVars { 2184 * public static String s = "a string"; 2185 * public static String s2 = "second string"; 2186 * public static String ns = null; 2187 * public static boolean b = false; 2188 * public static int i = 5; 2189 * @Debug.DebugProperty 2190 * public static float f = 0.1f; 2191 * @@Debug.DebugProperty 2192 * public static double d = 0.5d; 2193 * 2194 * // This MUST appear AFTER all fields are defined and initialized! 2195 * static { 2196 * // Sets all the fields 2197 * Debug.setFieldsOn(MyDebugVars.class); 2198 * 2199 * // Sets only the fields annotated with @Debug.DebugProperty 2200 * // Debug.setFieldsOn(MyDebugVars.class, true); 2201 * } 2202 * } 2203 * </pre> 2204 * setFieldsOn() may override the value of any field in the class based 2205 * on internal properties that are fixed at boot time. 2206 * <p> 2207 * These properties are only set during platform debugging, and are not 2208 * meant to be used as a general-purpose properties store. 2209 * 2210 * {@hide} 2211 * 2212 * @param cl The class to (possibly) modify 2213 * @param partial If false, sets all static fields, otherwise, only set 2214 * fields with the {@link android.os.Debug.DebugProperty} 2215 * annotation 2216 * @throws IllegalArgumentException if any fields are final or non-static, 2217 * or if the type of the field does not match the type of 2218 * the internal debugging property value. 2219 */ setFieldsOn(Class<?> cl, boolean partial)2220 public static void setFieldsOn(Class<?> cl, boolean partial) { 2221 if (false) { 2222 if (debugProperties != null) { 2223 /* Only look for fields declared directly by the class, 2224 * so we don't mysteriously change static fields in superclasses. 2225 */ 2226 for (Field field : cl.getDeclaredFields()) { 2227 if (!partial || field.getAnnotation(DebugProperty.class) != null) { 2228 final String propertyName = cl.getName() + "." + field.getName(); 2229 boolean isStatic = Modifier.isStatic(field.getModifiers()); 2230 boolean isFinal = Modifier.isFinal(field.getModifiers()); 2231 2232 if (!isStatic || isFinal) { 2233 throw new IllegalArgumentException(propertyName + 2234 " must be static and non-final"); 2235 } 2236 modifyFieldIfSet(field, debugProperties, propertyName); 2237 } 2238 } 2239 } 2240 } else { 2241 Log.wtf(TAG, 2242 "setFieldsOn(" + (cl == null ? "null" : cl.getName()) + 2243 ") called in non-DEBUG build"); 2244 } 2245 } 2246 2247 /** 2248 * Annotation to put on fields you want to set with 2249 * {@link Debug#setFieldsOn(Class, boolean)}. 2250 * 2251 * @hide 2252 */ 2253 @Target({ ElementType.FIELD }) 2254 @Retention(RetentionPolicy.RUNTIME) 2255 public @interface DebugProperty { 2256 } 2257 2258 /** 2259 * Get a debugging dump of a system service by name. 2260 * 2261 * <p>Most services require the caller to hold android.permission.DUMP. 2262 * 2263 * @param name of the service to dump 2264 * @param fd to write dump output to (usually an output log file) 2265 * @param args to pass to the service's dump method, may be null 2266 * @return true if the service was dumped successfully, false if 2267 * the service could not be found or had an error while dumping 2268 */ dumpService(String name, FileDescriptor fd, String[] args)2269 public static boolean dumpService(String name, FileDescriptor fd, String[] args) { 2270 IBinder service = ServiceManager.getService(name); 2271 if (service == null) { 2272 Log.e(TAG, "Can't find service to dump: " + name); 2273 return false; 2274 } 2275 2276 try { 2277 service.dump(fd, args); 2278 return true; 2279 } catch (RemoteException e) { 2280 Log.e(TAG, "Can't dump service: " + name, e); 2281 return false; 2282 } 2283 } 2284 2285 /** 2286 * Append the Java stack traces of a given native process to a specified file. 2287 * 2288 * @param pid pid to dump. 2289 * @param file path of file to append dump to. 2290 * @param timeoutSecs time to wait in seconds, or 0 to wait forever. 2291 * @hide 2292 */ dumpJavaBacktraceToFileTimeout(int pid, String file, int timeoutSecs)2293 public static native boolean dumpJavaBacktraceToFileTimeout(int pid, String file, 2294 int timeoutSecs); 2295 2296 /** 2297 * Append the native stack traces of a given process to a specified file. 2298 * 2299 * @param pid pid to dump. 2300 * @param file path of file to append dump to. 2301 * @param timeoutSecs time to wait in seconds, or 0 to wait forever. 2302 * @hide 2303 */ dumpNativeBacktraceToFileTimeout(int pid, String file, int timeoutSecs)2304 public static native boolean dumpNativeBacktraceToFileTimeout(int pid, String file, 2305 int timeoutSecs); 2306 2307 /** 2308 * Get description of unreachable native memory. 2309 * @param limit the number of leaks to provide info on, 0 to only get a summary. 2310 * @param contents true to include a hex dump of the contents of unreachable memory. 2311 * @return the String containing a description of unreachable memory. 2312 * @hide */ getUnreachableMemory(int limit, boolean contents)2313 public static native String getUnreachableMemory(int limit, boolean contents); 2314 2315 /** 2316 * Return a String describing the calling method and location at a particular stack depth. 2317 * @param callStack the Thread stack 2318 * @param depth the depth of stack to return information for. 2319 * @return the String describing the caller at that depth. 2320 */ getCaller(StackTraceElement callStack[], int depth)2321 private static String getCaller(StackTraceElement callStack[], int depth) { 2322 // callStack[4] is the caller of the method that called getCallers() 2323 if (4 + depth >= callStack.length) { 2324 return "<bottom of call stack>"; 2325 } 2326 StackTraceElement caller = callStack[4 + depth]; 2327 return caller.getClassName() + "." + caller.getMethodName() + ":" + caller.getLineNumber(); 2328 } 2329 2330 /** 2331 * Return a string consisting of methods and locations at multiple call stack levels. 2332 * @param depth the number of levels to return, starting with the immediate caller. 2333 * @return a string describing the call stack. 2334 * {@hide} 2335 */ getCallers(final int depth)2336 public static String getCallers(final int depth) { 2337 final StackTraceElement[] callStack = Thread.currentThread().getStackTrace(); 2338 StringBuffer sb = new StringBuffer(); 2339 for (int i = 0; i < depth; i++) { 2340 sb.append(getCaller(callStack, i)).append(" "); 2341 } 2342 return sb.toString(); 2343 } 2344 2345 /** 2346 * Return a string consisting of methods and locations at multiple call stack levels. 2347 * @param depth the number of levels to return, starting with the immediate caller. 2348 * @return a string describing the call stack. 2349 * {@hide} 2350 */ getCallers(final int start, int depth)2351 public static String getCallers(final int start, int depth) { 2352 final StackTraceElement[] callStack = Thread.currentThread().getStackTrace(); 2353 StringBuffer sb = new StringBuffer(); 2354 depth += start; 2355 for (int i = start; i < depth; i++) { 2356 sb.append(getCaller(callStack, i)).append(" "); 2357 } 2358 return sb.toString(); 2359 } 2360 2361 /** 2362 * Like {@link #getCallers(int)}, but each location is append to the string 2363 * as a new line with <var>linePrefix</var> in front of it. 2364 * @param depth the number of levels to return, starting with the immediate caller. 2365 * @param linePrefix prefix to put in front of each location. 2366 * @return a string describing the call stack. 2367 * {@hide} 2368 */ getCallers(final int depth, String linePrefix)2369 public static String getCallers(final int depth, String linePrefix) { 2370 final StackTraceElement[] callStack = Thread.currentThread().getStackTrace(); 2371 StringBuffer sb = new StringBuffer(); 2372 for (int i = 0; i < depth; i++) { 2373 sb.append(linePrefix).append(getCaller(callStack, i)).append("\n"); 2374 } 2375 return sb.toString(); 2376 } 2377 2378 /** 2379 * @return a String describing the immediate caller of the calling method. 2380 * {@hide} 2381 */ getCaller()2382 public static String getCaller() { 2383 return getCaller(Thread.currentThread().getStackTrace(), 0); 2384 } 2385 } 2386