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