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