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 a debugger attaches, 986 * suspend all Java threads and send VM_START (a.k.a VM_INIT) 987 * packet. 988 * 989 * @hide 990 */ suspendAllAndSendVmStart()991 public static void suspendAllAndSendVmStart() { 992 if (!VMDebug.isDebuggingEnabled()) { 993 return; 994 } 995 996 // if DDMS is listening, inform them of our plight 997 System.out.println("Sending WAIT chunk"); 998 byte[] data = new byte[] { 0 }; // 0 == "waiting for debugger" 999 Chunk waitChunk = new Chunk(ChunkHandler.type("WAIT"), data, 0, 1); 1000 DdmServer.sendChunk(waitChunk); 1001 1002 // We must wait until a debugger is connected (debug socket is 1003 // open and at least one non-DDM JDWP packedt has been received. 1004 // This guarantees that oj-libjdwp has been attached and that 1005 // ART's default implementation of suspendAllAndSendVmStart has 1006 // been replaced with an implementation that will suspendAll and 1007 // send VM_START. 1008 System.out.println("Waiting for debugger first packet"); 1009 1010 mWaiting = true; 1011 while (!isDebuggerConnected()) { 1012 try { 1013 Thread.sleep(100); 1014 } catch (InterruptedException ie) { 1015 } 1016 } 1017 mWaiting = false; 1018 1019 System.out.println("Debug.suspendAllAndSentVmStart"); 1020 VMDebug.suspendAllAndSendVmStart(); 1021 System.out.println("Debug.suspendAllAndSendVmStart, resumed"); 1022 } 1023 1024 /** 1025 * Wait until a debugger attaches. As soon as the debugger attaches, 1026 * this returns, so you will need to place a breakpoint after the 1027 * waitForDebugger() call if you want to start tracing immediately. 1028 */ waitForDebugger()1029 public static void waitForDebugger() { 1030 if (!VMDebug.isDebuggingEnabled()) { 1031 //System.out.println("debugging not enabled, not waiting"); 1032 return; 1033 } 1034 if (isDebuggerConnected()) 1035 return; 1036 1037 // if DDMS is listening, inform them of our plight 1038 System.out.println("Sending WAIT chunk"); 1039 byte[] data = new byte[] { 0 }; // 0 == "waiting for debugger" 1040 Chunk waitChunk = new Chunk(ChunkHandler.type("WAIT"), data, 0, 1); 1041 DdmServer.sendChunk(waitChunk); 1042 1043 mWaiting = true; 1044 while (!isDebuggerConnected()) { 1045 try { Thread.sleep(SPIN_DELAY); } 1046 catch (InterruptedException ie) {} 1047 } 1048 mWaiting = false; 1049 1050 System.out.println("Debugger has connected"); 1051 1052 /* 1053 * There is no "ready to go" signal from the debugger, and we're 1054 * not allowed to suspend ourselves -- the debugger expects us to 1055 * be running happily, and gets confused if we aren't. We need to 1056 * allow the debugger a chance to set breakpoints before we start 1057 * running again. 1058 * 1059 * Sit and spin until the debugger has been idle for a short while. 1060 */ 1061 while (true) { 1062 long delta = VMDebug.lastDebuggerActivity(); 1063 if (delta < 0) { 1064 System.out.println("debugger detached?"); 1065 break; 1066 } 1067 1068 if (delta < MIN_DEBUGGER_IDLE) { 1069 System.out.println("waiting for debugger to settle..."); 1070 try { Thread.sleep(SPIN_DELAY); } 1071 catch (InterruptedException ie) {} 1072 } else { 1073 System.out.println("debugger has settled (" + delta + ")"); 1074 break; 1075 } 1076 } 1077 } 1078 1079 /** 1080 * Returns "true" if one or more threads is waiting for a debugger 1081 * to attach. 1082 */ waitingForDebugger()1083 public static boolean waitingForDebugger() { 1084 return mWaiting; 1085 } 1086 1087 /** 1088 * Determine if a debugger is currently attached. 1089 */ isDebuggerConnected()1090 public static boolean isDebuggerConnected() { 1091 return VMDebug.isDebuggerConnected(); 1092 } 1093 1094 /** 1095 * Returns an array of strings that identify VM features. This is 1096 * used by DDMS to determine what sorts of operations the VM can 1097 * perform. 1098 * 1099 * @hide 1100 */ getVmFeatureList()1101 public static String[] getVmFeatureList() { 1102 return VMDebug.getVmFeatureList(); 1103 } 1104 1105 /** 1106 * Change the JDWP port. 1107 * 1108 * @deprecated no longer needed or useful 1109 */ 1110 @Deprecated changeDebugPort(int port)1111 public static void changeDebugPort(int port) {} 1112 1113 /** 1114 * This is the pathname to the sysfs file that enables and disables 1115 * tracing on the qemu emulator. 1116 */ 1117 private static final String SYSFS_QEMU_TRACE_STATE = "/sys/qemu_trace/state"; 1118 1119 /** 1120 * Enable qemu tracing. For this to work requires running everything inside 1121 * the qemu emulator; otherwise, this method will have no effect. The trace 1122 * file is specified on the command line when the emulator is started. For 1123 * example, the following command line <br /> 1124 * <code>emulator -trace foo</code><br /> 1125 * will start running the emulator and create a trace file named "foo". This 1126 * method simply enables writing the trace records to the trace file. 1127 * 1128 * <p> 1129 * The main differences between this and {@link #startMethodTracing()} are 1130 * that tracing in the qemu emulator traces every cpu instruction of every 1131 * process, including kernel code, so we have more complete information, 1132 * including all context switches. We can also get more detailed information 1133 * such as cache misses. The sequence of calls is determined by 1134 * post-processing the instruction trace. The qemu tracing is also done 1135 * without modifying the application or perturbing the timing of calls 1136 * because no instrumentation is added to the application being traced. 1137 * </p> 1138 * 1139 * <p> 1140 * One limitation of using this method compared to using 1141 * {@link #startMethodTracing()} on the real device is that the emulator 1142 * does not model all of the real hardware effects such as memory and 1143 * bus contention. The emulator also has a simple cache model and cannot 1144 * capture all the complexities of a real cache. 1145 * </p> 1146 */ startNativeTracing()1147 public static void startNativeTracing() { 1148 // Open the sysfs file for writing and write "1" to it. 1149 PrintWriter outStream = null; 1150 try { 1151 FileOutputStream fos = new FileOutputStream(SYSFS_QEMU_TRACE_STATE); 1152 outStream = new FastPrintWriter(fos); 1153 outStream.println("1"); 1154 } catch (Exception e) { 1155 } finally { 1156 if (outStream != null) 1157 outStream.close(); 1158 } 1159 } 1160 1161 /** 1162 * Stop qemu tracing. See {@link #startNativeTracing()} to start tracing. 1163 * 1164 * <p>Tracing can be started and stopped as many times as desired. When 1165 * the qemu emulator itself is stopped then the buffered trace records 1166 * are flushed and written to the trace file. In fact, it is not necessary 1167 * to call this method at all; simply killing qemu is sufficient. But 1168 * starting and stopping a trace is useful for examining a specific 1169 * region of code.</p> 1170 */ stopNativeTracing()1171 public static void stopNativeTracing() { 1172 // Open the sysfs file for writing and write "0" to it. 1173 PrintWriter outStream = null; 1174 try { 1175 FileOutputStream fos = new FileOutputStream(SYSFS_QEMU_TRACE_STATE); 1176 outStream = new FastPrintWriter(fos); 1177 outStream.println("0"); 1178 } catch (Exception e) { 1179 // We could print an error message here but we probably want 1180 // to quietly ignore errors if we are not running in the emulator. 1181 } finally { 1182 if (outStream != null) 1183 outStream.close(); 1184 } 1185 } 1186 1187 /** 1188 * Enable "emulator traces", in which information about the current 1189 * method is made available to the "emulator -trace" feature. There 1190 * is no corresponding "disable" call -- this is intended for use by 1191 * the framework when tracing should be turned on and left that way, so 1192 * that traces captured with F9/F10 will include the necessary data. 1193 * 1194 * This puts the VM into "profile" mode, which has performance 1195 * consequences. 1196 * 1197 * To temporarily enable tracing, use {@link #startNativeTracing()}. 1198 * 1199 * @deprecated Please use other tracing method in this class. 1200 */ enableEmulatorTraceOutput()1201 public static void enableEmulatorTraceOutput() { 1202 Log.w(TAG, "Unimplemented"); 1203 } 1204 1205 /** 1206 * Start method tracing with default log name and buffer size. 1207 * <p> 1208 * By default, the trace file is called "dmtrace.trace" and it's placed 1209 * under your package-specific directory on primary shared/external storage, 1210 * as returned by {@link Context#getExternalFilesDir(String)}. 1211 * <p> 1212 * See <a href="{@docRoot}studio/profile/traceview.html">Inspect Trace Logs 1213 * with Traceview</a> for information about reading trace files. 1214 * <p class="note"> 1215 * When method tracing is enabled, the VM will run more slowly than usual, 1216 * so the timings from the trace files should only be considered in relative 1217 * terms (e.g. was run #1 faster than run #2). The times for native methods 1218 * will not change, so don't try to use this to compare the performance of 1219 * interpreted and native implementations of the same method. As an 1220 * alternative, consider using sampling-based method tracing via 1221 * {@link #startMethodTracingSampling(String, int, int)} or "native" tracing 1222 * in the emulator via {@link #startNativeTracing()}. 1223 * </p> 1224 */ startMethodTracing()1225 public static void startMethodTracing() { 1226 VMDebug.startMethodTracing(fixTracePath(null), 0, 0, false, 0); 1227 } 1228 1229 /** 1230 * Start method tracing, specifying the trace log file path. 1231 * <p> 1232 * When a relative file path is given, the trace file will be placed under 1233 * your package-specific directory on primary shared/external storage, as 1234 * returned by {@link Context#getExternalFilesDir(String)}. 1235 * <p> 1236 * See <a href="{@docRoot}studio/profile/traceview.html">Inspect Trace Logs 1237 * with Traceview</a> for information about reading trace files. 1238 * <p class="note"> 1239 * When method tracing is enabled, the VM will run more slowly than usual, 1240 * so the timings from the trace files should only be considered in relative 1241 * terms (e.g. was run #1 faster than run #2). The times for native methods 1242 * will not change, so don't try to use this to compare the performance of 1243 * interpreted and native implementations of the same method. As an 1244 * alternative, consider using sampling-based method tracing via 1245 * {@link #startMethodTracingSampling(String, int, int)} or "native" tracing 1246 * in the emulator via {@link #startNativeTracing()}. 1247 * </p> 1248 * 1249 * @param tracePath Path to the trace log file to create. If {@code null}, 1250 * this will default to "dmtrace.trace". If the file already 1251 * exists, it will be truncated. If the path given does not end 1252 * in ".trace", it will be appended for you. 1253 */ startMethodTracing(String tracePath)1254 public static void startMethodTracing(String tracePath) { 1255 startMethodTracing(tracePath, 0, 0); 1256 } 1257 1258 /** 1259 * Start method tracing, specifying the trace log file name and the buffer 1260 * size. 1261 * <p> 1262 * When a relative file path is given, the trace file will be placed under 1263 * your package-specific directory on primary shared/external storage, as 1264 * returned by {@link Context#getExternalFilesDir(String)}. 1265 * <p> 1266 * See <a href="{@docRoot}studio/profile/traceview.html">Inspect Trace Logs 1267 * with Traceview</a> for information about reading trace files. 1268 * <p class="note"> 1269 * When method tracing is enabled, the VM will run more slowly than usual, 1270 * so the timings from the trace files should only be considered in relative 1271 * terms (e.g. was run #1 faster than run #2). The times for native methods 1272 * will not change, so don't try to use this to compare the performance of 1273 * interpreted and native implementations of the same method. As an 1274 * alternative, consider using sampling-based method tracing via 1275 * {@link #startMethodTracingSampling(String, int, int)} or "native" tracing 1276 * in the emulator via {@link #startNativeTracing()}. 1277 * </p> 1278 * 1279 * @param tracePath Path to the trace log file to create. If {@code null}, 1280 * this will default to "dmtrace.trace". If the file already 1281 * exists, it will be truncated. If the path given does not end 1282 * in ".trace", it will be appended for you. 1283 * @param bufferSize The maximum amount of trace data we gather. If not 1284 * given, it defaults to 8MB. 1285 */ startMethodTracing(String tracePath, int bufferSize)1286 public static void startMethodTracing(String tracePath, int bufferSize) { 1287 startMethodTracing(tracePath, bufferSize, 0); 1288 } 1289 1290 /** 1291 * Start method tracing, specifying the trace log file name, the buffer 1292 * size, and flags. 1293 * <p> 1294 * When a relative file path is given, the trace file will be placed under 1295 * your package-specific directory on primary shared/external storage, as 1296 * returned by {@link Context#getExternalFilesDir(String)}. 1297 * <p> 1298 * See <a href="{@docRoot}studio/profile/traceview.html">Inspect Trace Logs 1299 * with Traceview</a> for information about reading trace files. 1300 * <p class="note"> 1301 * When method tracing is enabled, the VM will run more slowly than usual, 1302 * so the timings from the trace files should only be considered in relative 1303 * terms (e.g. was run #1 faster than run #2). The times for native methods 1304 * will not change, so don't try to use this to compare the performance of 1305 * interpreted and native implementations of the same method. As an 1306 * alternative, consider using sampling-based method tracing via 1307 * {@link #startMethodTracingSampling(String, int, int)} or "native" tracing 1308 * in the emulator via {@link #startNativeTracing()}. 1309 * </p> 1310 * 1311 * @param tracePath Path to the trace log file to create. If {@code null}, 1312 * this will default to "dmtrace.trace". If the file already 1313 * exists, it will be truncated. If the path given does not end 1314 * in ".trace", it will be appended for you. 1315 * @param bufferSize The maximum amount of trace data we gather. If not 1316 * given, it defaults to 8MB. 1317 * @param flags Flags to control method tracing. The only one that is 1318 * currently defined is {@link #TRACE_COUNT_ALLOCS}. 1319 */ startMethodTracing(String tracePath, int bufferSize, int flags)1320 public static void startMethodTracing(String tracePath, int bufferSize, int flags) { 1321 VMDebug.startMethodTracing(fixTracePath(tracePath), bufferSize, flags, false, 0); 1322 } 1323 1324 /** 1325 * Start sampling-based method tracing, specifying the trace log file name, 1326 * the buffer size, and the sampling interval. 1327 * <p> 1328 * When a relative file path is given, the trace file will be placed under 1329 * your package-specific directory on primary shared/external storage, as 1330 * returned by {@link Context#getExternalFilesDir(String)}. 1331 * <p> 1332 * See <a href="{@docRoot}studio/profile/traceview.html">Inspect Trace Logs 1333 * with Traceview</a> for information about reading trace files. 1334 * 1335 * @param tracePath Path to the trace log file to create. If {@code null}, 1336 * this will default to "dmtrace.trace". If the file already 1337 * exists, it will be truncated. If the path given does not end 1338 * in ".trace", it will be appended for you. 1339 * @param bufferSize The maximum amount of trace data we gather. If not 1340 * given, it defaults to 8MB. 1341 * @param intervalUs The amount of time between each sample in microseconds. 1342 */ startMethodTracingSampling(String tracePath, int bufferSize, int intervalUs)1343 public static void startMethodTracingSampling(String tracePath, int bufferSize, 1344 int intervalUs) { 1345 VMDebug.startMethodTracing(fixTracePath(tracePath), bufferSize, 0, true, intervalUs); 1346 } 1347 1348 /** 1349 * Formats name of trace log file for method tracing. 1350 */ fixTracePath(String tracePath)1351 private static String fixTracePath(String tracePath) { 1352 if (tracePath == null || tracePath.charAt(0) != '/') { 1353 final Context context = AppGlobals.getInitialApplication(); 1354 final File dir; 1355 if (context != null) { 1356 dir = context.getExternalFilesDir(null); 1357 } else { 1358 dir = Environment.getExternalStorageDirectory(); 1359 } 1360 1361 if (tracePath == null) { 1362 tracePath = new File(dir, DEFAULT_TRACE_BODY).getAbsolutePath(); 1363 } else { 1364 tracePath = new File(dir, tracePath).getAbsolutePath(); 1365 } 1366 } 1367 if (!tracePath.endsWith(DEFAULT_TRACE_EXTENSION)) { 1368 tracePath += DEFAULT_TRACE_EXTENSION; 1369 } 1370 return tracePath; 1371 } 1372 1373 /** 1374 * Like startMethodTracing(String, int, int), but taking an already-opened 1375 * FileDescriptor in which the trace is written. The file name is also 1376 * supplied simply for logging. Makes a dup of the file descriptor. 1377 * 1378 * Not exposed in the SDK unless we are really comfortable with supporting 1379 * this and find it would be useful. 1380 * @hide 1381 */ startMethodTracing(String traceName, FileDescriptor fd, int bufferSize, int flags, boolean streamOutput)1382 public static void startMethodTracing(String traceName, FileDescriptor fd, 1383 int bufferSize, int flags, boolean streamOutput) { 1384 VMDebug.startMethodTracing(traceName, fd, bufferSize, flags, false, 0, streamOutput); 1385 } 1386 1387 /** 1388 * Starts method tracing without a backing file. When stopMethodTracing 1389 * is called, the result is sent directly to DDMS. (If DDMS is not 1390 * attached when tracing ends, the profiling data will be discarded.) 1391 * 1392 * @hide 1393 */ startMethodTracingDdms(int bufferSize, int flags, boolean samplingEnabled, int intervalUs)1394 public static void startMethodTracingDdms(int bufferSize, int flags, 1395 boolean samplingEnabled, int intervalUs) { 1396 VMDebug.startMethodTracingDdms(bufferSize, flags, samplingEnabled, intervalUs); 1397 } 1398 1399 /** 1400 * Determine whether method tracing is currently active and what type is 1401 * active. 1402 * 1403 * @hide 1404 */ getMethodTracingMode()1405 public static int getMethodTracingMode() { 1406 return VMDebug.getMethodTracingMode(); 1407 } 1408 1409 /** 1410 * Stop method tracing. 1411 */ stopMethodTracing()1412 public static void stopMethodTracing() { 1413 VMDebug.stopMethodTracing(); 1414 } 1415 1416 /** 1417 * Get an indication of thread CPU usage. The value returned 1418 * indicates the amount of time that the current thread has spent 1419 * executing code or waiting for certain types of I/O. 1420 * 1421 * The time is expressed in nanoseconds, and is only meaningful 1422 * when compared to the result from an earlier call. Note that 1423 * nanosecond resolution does not imply nanosecond accuracy. 1424 * 1425 * On system which don't support this operation, the call returns -1. 1426 */ threadCpuTimeNanos()1427 public static long threadCpuTimeNanos() { 1428 return VMDebug.threadCpuTimeNanos(); 1429 } 1430 1431 /** 1432 * Start counting the number and aggregate size of memory allocations. 1433 * 1434 * <p>The {@link #startAllocCounting() start} method resets the counts and enables counting. 1435 * The {@link #stopAllocCounting() stop} method disables the counting so that the analysis 1436 * code doesn't cause additional allocations. The various <code>get</code> methods return 1437 * the specified value. And the various <code>reset</code> methods reset the specified 1438 * count.</p> 1439 * 1440 * <p>Counts are kept for the system as a whole (global) and for each thread. 1441 * The per-thread counts for threads other than the current thread 1442 * are not cleared by the "reset" or "start" calls.</p> 1443 * 1444 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1445 */ 1446 @Deprecated startAllocCounting()1447 public static void startAllocCounting() { 1448 VMDebug.startAllocCounting(); 1449 } 1450 1451 /** 1452 * Stop counting the number and aggregate size of memory allocations. 1453 * 1454 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1455 */ 1456 @Deprecated stopAllocCounting()1457 public static void stopAllocCounting() { 1458 VMDebug.stopAllocCounting(); 1459 } 1460 1461 /** 1462 * Returns the global count of objects allocated by the runtime between a 1463 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1464 * 1465 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1466 */ 1467 @Deprecated getGlobalAllocCount()1468 public static int getGlobalAllocCount() { 1469 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_OBJECTS); 1470 } 1471 1472 /** 1473 * Clears the global count of objects allocated. 1474 * @see #getGlobalAllocCount() 1475 * 1476 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1477 */ 1478 @Deprecated resetGlobalAllocCount()1479 public static void resetGlobalAllocCount() { 1480 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_OBJECTS); 1481 } 1482 1483 /** 1484 * Returns the global size, in bytes, of objects allocated by the runtime between a 1485 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1486 * 1487 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1488 */ 1489 @Deprecated getGlobalAllocSize()1490 public static int getGlobalAllocSize() { 1491 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_BYTES); 1492 } 1493 1494 /** 1495 * Clears the global size of objects allocated. 1496 * @see #getGlobalAllocSize() 1497 * 1498 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1499 */ 1500 @Deprecated resetGlobalAllocSize()1501 public static void resetGlobalAllocSize() { 1502 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_BYTES); 1503 } 1504 1505 /** 1506 * Returns the global count of objects freed by the runtime between a 1507 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1508 * 1509 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1510 */ 1511 @Deprecated getGlobalFreedCount()1512 public static int getGlobalFreedCount() { 1513 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_FREED_OBJECTS); 1514 } 1515 1516 /** 1517 * Clears the global count of objects freed. 1518 * @see #getGlobalFreedCount() 1519 * 1520 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1521 */ 1522 @Deprecated resetGlobalFreedCount()1523 public static void resetGlobalFreedCount() { 1524 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_FREED_OBJECTS); 1525 } 1526 1527 /** 1528 * Returns the global size, in bytes, of objects freed by the runtime between a 1529 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1530 * 1531 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1532 */ 1533 @Deprecated getGlobalFreedSize()1534 public static int getGlobalFreedSize() { 1535 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_FREED_BYTES); 1536 } 1537 1538 /** 1539 * Clears the global size of objects freed. 1540 * @see #getGlobalFreedSize() 1541 * 1542 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1543 */ 1544 @Deprecated resetGlobalFreedSize()1545 public static void resetGlobalFreedSize() { 1546 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_FREED_BYTES); 1547 } 1548 1549 /** 1550 * Returns the number of non-concurrent GC invocations between a 1551 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1552 * 1553 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1554 */ 1555 @Deprecated getGlobalGcInvocationCount()1556 public static int getGlobalGcInvocationCount() { 1557 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_GC_INVOCATIONS); 1558 } 1559 1560 /** 1561 * Clears the count of non-concurrent GC invocations. 1562 * @see #getGlobalGcInvocationCount() 1563 * 1564 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1565 */ 1566 @Deprecated resetGlobalGcInvocationCount()1567 public static void resetGlobalGcInvocationCount() { 1568 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_GC_INVOCATIONS); 1569 } 1570 1571 /** 1572 * Returns the number of classes successfully initialized (ie those that executed without 1573 * throwing an exception) between a {@link #startAllocCounting() start} and 1574 * {@link #stopAllocCounting() stop}. 1575 * 1576 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1577 */ 1578 @Deprecated getGlobalClassInitCount()1579 public static int getGlobalClassInitCount() { 1580 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_COUNT); 1581 } 1582 1583 /** 1584 * Clears the count of classes initialized. 1585 * @see #getGlobalClassInitCount() 1586 * 1587 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1588 */ 1589 @Deprecated resetGlobalClassInitCount()1590 public static void resetGlobalClassInitCount() { 1591 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_COUNT); 1592 } 1593 1594 /** 1595 * Returns the time spent successfully initializing classes between a 1596 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1597 * 1598 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1599 */ 1600 @Deprecated getGlobalClassInitTime()1601 public static int getGlobalClassInitTime() { 1602 /* cumulative elapsed time for class initialization, in usec */ 1603 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_TIME); 1604 } 1605 1606 /** 1607 * Clears the count of time spent initializing classes. 1608 * @see #getGlobalClassInitTime() 1609 * 1610 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1611 */ 1612 @Deprecated resetGlobalClassInitTime()1613 public static void resetGlobalClassInitTime() { 1614 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_TIME); 1615 } 1616 1617 /** 1618 * This method exists for compatibility and always returns 0. 1619 * @deprecated This method is now obsolete. 1620 */ 1621 @Deprecated getGlobalExternalAllocCount()1622 public static int getGlobalExternalAllocCount() { 1623 return 0; 1624 } 1625 1626 /** 1627 * This method exists for compatibility and has no effect. 1628 * @deprecated This method is now obsolete. 1629 */ 1630 @Deprecated resetGlobalExternalAllocSize()1631 public static void resetGlobalExternalAllocSize() {} 1632 1633 /** 1634 * This method exists for compatibility and has no effect. 1635 * @deprecated This method is now obsolete. 1636 */ 1637 @Deprecated resetGlobalExternalAllocCount()1638 public static void resetGlobalExternalAllocCount() {} 1639 1640 /** 1641 * This method exists for compatibility and always returns 0. 1642 * @deprecated This method is now obsolete. 1643 */ 1644 @Deprecated getGlobalExternalAllocSize()1645 public static int getGlobalExternalAllocSize() { 1646 return 0; 1647 } 1648 1649 /** 1650 * This method exists for compatibility and always returns 0. 1651 * @deprecated This method is now obsolete. 1652 */ 1653 @Deprecated getGlobalExternalFreedCount()1654 public static int getGlobalExternalFreedCount() { 1655 return 0; 1656 } 1657 1658 /** 1659 * This method exists for compatibility and has no effect. 1660 * @deprecated This method is now obsolete. 1661 */ 1662 @Deprecated resetGlobalExternalFreedCount()1663 public static void resetGlobalExternalFreedCount() {} 1664 1665 /** 1666 * This method exists for compatibility and has no effect. 1667 * @deprecated This method is now obsolete. 1668 */ 1669 @Deprecated getGlobalExternalFreedSize()1670 public static int getGlobalExternalFreedSize() { 1671 return 0; 1672 } 1673 1674 /** 1675 * This method exists for compatibility and has no effect. 1676 * @deprecated This method is now obsolete. 1677 */ 1678 @Deprecated resetGlobalExternalFreedSize()1679 public static void resetGlobalExternalFreedSize() {} 1680 1681 /** 1682 * Returns the thread-local count of objects allocated by the runtime between a 1683 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1684 * 1685 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1686 */ 1687 @Deprecated getThreadAllocCount()1688 public static int getThreadAllocCount() { 1689 return VMDebug.getAllocCount(VMDebug.KIND_THREAD_ALLOCATED_OBJECTS); 1690 } 1691 1692 /** 1693 * Clears the thread-local count of objects allocated. 1694 * @see #getThreadAllocCount() 1695 * 1696 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1697 */ 1698 @Deprecated resetThreadAllocCount()1699 public static void resetThreadAllocCount() { 1700 VMDebug.resetAllocCount(VMDebug.KIND_THREAD_ALLOCATED_OBJECTS); 1701 } 1702 1703 /** 1704 * Returns the thread-local size of objects allocated by the runtime between a 1705 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1706 * @return The allocated size in bytes. 1707 * 1708 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1709 */ 1710 @Deprecated getThreadAllocSize()1711 public static int getThreadAllocSize() { 1712 return VMDebug.getAllocCount(VMDebug.KIND_THREAD_ALLOCATED_BYTES); 1713 } 1714 1715 /** 1716 * Clears the thread-local count of objects allocated. 1717 * @see #getThreadAllocSize() 1718 * 1719 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1720 */ 1721 @Deprecated resetThreadAllocSize()1722 public static void resetThreadAllocSize() { 1723 VMDebug.resetAllocCount(VMDebug.KIND_THREAD_ALLOCATED_BYTES); 1724 } 1725 1726 /** 1727 * This method exists for compatibility and has no effect. 1728 * @deprecated This method is now obsolete. 1729 */ 1730 @Deprecated getThreadExternalAllocCount()1731 public static int getThreadExternalAllocCount() { 1732 return 0; 1733 } 1734 1735 /** 1736 * This method exists for compatibility and has no effect. 1737 * @deprecated This method is now obsolete. 1738 */ 1739 @Deprecated resetThreadExternalAllocCount()1740 public static void resetThreadExternalAllocCount() {} 1741 1742 /** 1743 * This method exists for compatibility and has no effect. 1744 * @deprecated This method is now obsolete. 1745 */ 1746 @Deprecated getThreadExternalAllocSize()1747 public static int getThreadExternalAllocSize() { 1748 return 0; 1749 } 1750 1751 /** 1752 * This method exists for compatibility and has no effect. 1753 * @deprecated This method is now obsolete. 1754 */ 1755 @Deprecated resetThreadExternalAllocSize()1756 public static void resetThreadExternalAllocSize() {} 1757 1758 /** 1759 * Returns the number of thread-local non-concurrent GC invocations between a 1760 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 1761 * 1762 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1763 */ 1764 @Deprecated getThreadGcInvocationCount()1765 public static int getThreadGcInvocationCount() { 1766 return VMDebug.getAllocCount(VMDebug.KIND_THREAD_GC_INVOCATIONS); 1767 } 1768 1769 /** 1770 * Clears the thread-local count of non-concurrent GC invocations. 1771 * @see #getThreadGcInvocationCount() 1772 * 1773 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1774 */ 1775 @Deprecated resetThreadGcInvocationCount()1776 public static void resetThreadGcInvocationCount() { 1777 VMDebug.resetAllocCount(VMDebug.KIND_THREAD_GC_INVOCATIONS); 1778 } 1779 1780 /** 1781 * Clears all the global and thread-local memory allocation counters. 1782 * @see #startAllocCounting() 1783 * 1784 * @deprecated Accurate counting is a burden on the runtime and may be removed. 1785 */ 1786 @Deprecated resetAllCounts()1787 public static void resetAllCounts() { 1788 VMDebug.resetAllocCount(VMDebug.KIND_ALL_COUNTS); 1789 } 1790 1791 /** 1792 * Returns the value of a particular runtime statistic or {@code null} if no 1793 * such runtime statistic exists. 1794 * 1795 * <p>The following table lists the runtime statistics that the runtime supports. 1796 * All statistics are approximate. Individual allocations may not be immediately reflected 1797 * in the results. 1798 * Note runtime statistics may be added or removed in a future API level.</p> 1799 * 1800 * <table> 1801 * <thead> 1802 * <tr> 1803 * <th>Runtime statistic name</th> 1804 * <th>Meaning</th> 1805 * <th>Example</th> 1806 * <th>Supported (API Levels)</th> 1807 * </tr> 1808 * </thead> 1809 * <tbody> 1810 * <tr> 1811 * <td>art.gc.gc-count</td> 1812 * <td>The number of garbage collection runs.</td> 1813 * <td>{@code 164}</td> 1814 * <td>23</td> 1815 * </tr> 1816 * <tr> 1817 * <td>art.gc.gc-time</td> 1818 * <td>The total duration of garbage collection runs in ms.</td> 1819 * <td>{@code 62364}</td> 1820 * <td>23</td> 1821 * </tr> 1822 * <tr> 1823 * <td>art.gc.bytes-allocated</td> 1824 * <td>The total number of bytes that the application allocated.</td> 1825 * <td>{@code 1463948408}</td> 1826 * <td>23</td> 1827 * </tr> 1828 * <tr> 1829 * <td>art.gc.bytes-freed</td> 1830 * <td>The total number of bytes that garbage collection reclaimed.</td> 1831 * <td>{@code 1313493084}</td> 1832 * <td>23</td> 1833 * </tr> 1834 * <tr> 1835 * <td>art.gc.blocking-gc-count</td> 1836 * <td>The number of blocking garbage collection runs.</td> 1837 * <td>{@code 2}</td> 1838 * <td>23</td> 1839 * </tr> 1840 * <tr> 1841 * <td>art.gc.blocking-gc-time</td> 1842 * <td>The total duration of blocking garbage collection runs in ms.</td> 1843 * <td>{@code 804}</td> 1844 * <td>23</td> 1845 * </tr> 1846 * <tr> 1847 * <td>art.gc.gc-count-rate-histogram</td> 1848 * <td>Every 10 seconds, the gc-count-rate is computed as the number of garbage 1849 * collection runs that have occurred over the last 10 1850 * seconds. art.gc.gc-count-rate-histogram is a histogram of the gc-count-rate 1851 * samples taken since the process began. The histogram can be used to identify 1852 * instances of high rates of garbage collection runs. For example, a histogram 1853 * of "0:34503,1:45350,2:11281,3:8088,4:43,5:8" shows that most of the time 1854 * there are between 0 and 2 garbage collection runs every 10 seconds, but there 1855 * were 8 distinct 10-second intervals in which 5 garbage collection runs 1856 * occurred.</td> 1857 * <td>{@code 0:34503,1:45350,2:11281,3:8088,4:43,5:8}</td> 1858 * <td>23</td> 1859 * </tr> 1860 * <tr> 1861 * <td>art.gc.blocking-gc-count-rate-histogram</td> 1862 * <td>Every 10 seconds, the blocking-gc-count-rate is computed as the number of 1863 * blocking garbage collection runs that have occurred over the last 10 1864 * seconds. art.gc.blocking-gc-count-rate-histogram is a histogram of the 1865 * blocking-gc-count-rate samples taken since the process began. The histogram 1866 * can be used to identify instances of high rates of blocking garbage 1867 * collection runs. For example, a histogram of "0:99269,1:1,2:1" shows that 1868 * most of the time there are zero blocking garbage collection runs every 10 1869 * seconds, but there was one 10-second interval in which one blocking garbage 1870 * collection run occurred, and there was one interval in which two blocking 1871 * garbage collection runs occurred.</td> 1872 * <td>{@code 0:99269,1:1,2:1}</td> 1873 * <td>23</td> 1874 * </tr> 1875 * </tbody> 1876 * </table> 1877 * 1878 * @param statName 1879 * the name of the runtime statistic to look up. 1880 * @return the value of the specified runtime statistic or {@code null} if the 1881 * runtime statistic doesn't exist. 1882 */ getRuntimeStat(String statName)1883 public static String getRuntimeStat(String statName) { 1884 return VMDebug.getRuntimeStat(statName); 1885 } 1886 1887 /** 1888 * Returns a map of the names/values of the runtime statistics 1889 * that {@link #getRuntimeStat(String)} supports. 1890 * 1891 * @return a map of the names/values of the supported runtime statistics. 1892 */ getRuntimeStats()1893 public static Map<String, String> getRuntimeStats() { 1894 return VMDebug.getRuntimeStats(); 1895 } 1896 1897 /** 1898 * Returns the size of the native heap. 1899 * @return The size of the native heap in bytes. 1900 */ getNativeHeapSize()1901 public static native long getNativeHeapSize(); 1902 1903 /** 1904 * Returns the amount of allocated memory in the native heap. 1905 * @return The allocated size in bytes. 1906 */ getNativeHeapAllocatedSize()1907 public static native long getNativeHeapAllocatedSize(); 1908 1909 /** 1910 * Returns the amount of free memory in the native heap. 1911 * @return The freed size in bytes. 1912 */ getNativeHeapFreeSize()1913 public static native long getNativeHeapFreeSize(); 1914 1915 /** 1916 * Retrieves information about this processes memory usages. This information is broken down by 1917 * how much is in use by dalvik, the native heap, and everything else. 1918 * 1919 * <p><b>Note:</b> this method directly retrieves memory information for the given process 1920 * from low-level data available to it. It may not be able to retrieve information about 1921 * some protected allocations, such as graphics. If you want to be sure you can see 1922 * all information about allocations by the process, use 1923 * {@link android.app.ActivityManager#getProcessMemoryInfo(int[])} instead.</p> 1924 */ getMemoryInfo(MemoryInfo memoryInfo)1925 public static native void getMemoryInfo(MemoryInfo memoryInfo); 1926 1927 /** 1928 * Note: currently only works when the requested pid has the same UID 1929 * as the caller. 1930 * 1931 * @return true if the meminfo was read successfully, false if not (i.e., given pid has gone). 1932 * 1933 * @hide 1934 */ 1935 @UnsupportedAppUsage getMemoryInfo(int pid, MemoryInfo memoryInfo)1936 public static native boolean getMemoryInfo(int pid, MemoryInfo memoryInfo); 1937 1938 /** 1939 * Retrieves the PSS memory used by the process as given by the 1940 * smaps. 1941 */ getPss()1942 public static native long getPss(); 1943 1944 /** 1945 * Retrieves the PSS memory used by the process as given by the smaps. Optionally supply a long 1946 * array of up to 3 entries to also receive (up to 3 values in order): the Uss and SwapPss and 1947 * Rss (only filled in as of {@link android.os.Build.VERSION_CODES#P}) of the process, and 1948 * another array to also retrieve the separate memtrack sizes (up to 4 values in order): the 1949 * total memtrack reported size, memtrack graphics, memtrack gl and memtrack other. 1950 * 1951 * @return The PSS memory usage, or 0 if failed to retrieve (i.e., given pid has gone). 1952 * @hide 1953 */ getPss(int pid, long[] outUssSwapPssRss, long[] outMemtrack)1954 public static native long getPss(int pid, long[] outUssSwapPssRss, long[] outMemtrack); 1955 1956 /** @hide */ 1957 public static final int MEMINFO_TOTAL = 0; 1958 /** @hide */ 1959 public static final int MEMINFO_FREE = 1; 1960 /** @hide */ 1961 public static final int MEMINFO_BUFFERS = 2; 1962 /** @hide */ 1963 public static final int MEMINFO_CACHED = 3; 1964 /** @hide */ 1965 public static final int MEMINFO_SHMEM = 4; 1966 /** @hide */ 1967 public static final int MEMINFO_SLAB = 5; 1968 /** @hide */ 1969 public static final int MEMINFO_SLAB_RECLAIMABLE = 6; 1970 /** @hide */ 1971 public static final int MEMINFO_SLAB_UNRECLAIMABLE = 7; 1972 /** @hide */ 1973 public static final int MEMINFO_SWAP_TOTAL = 8; 1974 /** @hide */ 1975 public static final int MEMINFO_SWAP_FREE = 9; 1976 /** @hide */ 1977 public static final int MEMINFO_ZRAM_TOTAL = 10; 1978 /** @hide */ 1979 public static final int MEMINFO_MAPPED = 11; 1980 /** @hide */ 1981 public static final int MEMINFO_VM_ALLOC_USED = 12; 1982 /** @hide */ 1983 public static final int MEMINFO_PAGE_TABLES = 13; 1984 /** @hide */ 1985 public static final int MEMINFO_KERNEL_STACK = 14; 1986 /** 1987 * Note: MEMINFO_KRECLAIMABLE includes MEMINFO_SLAB_RECLAIMABLE (see KReclaimable field 1988 * description in kernel documentation). 1989 * @hide 1990 */ 1991 public static final int MEMINFO_KRECLAIMABLE = 15; 1992 /** @hide */ 1993 public static final int MEMINFO_ACTIVE = 16; 1994 /** @hide */ 1995 public static final int MEMINFO_INACTIVE = 17; 1996 /** @hide */ 1997 public static final int MEMINFO_UNEVICTABLE = 18; 1998 /** @hide */ 1999 public static final int MEMINFO_AVAILABLE = 19; 2000 /** @hide */ 2001 public static final int MEMINFO_ACTIVE_ANON = 20; 2002 /** @hide */ 2003 public static final int MEMINFO_INACTIVE_ANON = 21; 2004 /** @hide */ 2005 public static final int MEMINFO_ACTIVE_FILE = 22; 2006 /** @hide */ 2007 public static final int MEMINFO_INACTIVE_FILE = 23; 2008 /** @hide */ 2009 public static final int MEMINFO_CMA_TOTAL = 24; 2010 /** @hide */ 2011 public static final int MEMINFO_CMA_FREE = 25; 2012 /** @hide */ 2013 public static final int MEMINFO_COUNT = 26; 2014 2015 /** 2016 * Retrieves /proc/meminfo. outSizes is filled with fields 2017 * as defined by MEMINFO_* offsets. 2018 * @hide 2019 */ 2020 @UnsupportedAppUsage getMemInfo(long[] outSizes)2021 public static native void getMemInfo(long[] outSizes); 2022 2023 /** 2024 * Establish an object allocation limit in the current thread. 2025 * This feature was never enabled in release builds. The 2026 * allocation limits feature was removed in Honeycomb. This 2027 * method exists for compatibility and always returns -1 and has 2028 * no effect. 2029 * 2030 * @deprecated This method is now obsolete. 2031 */ 2032 @Deprecated setAllocationLimit(int limit)2033 public static int setAllocationLimit(int limit) { 2034 return -1; 2035 } 2036 2037 /** 2038 * Establish a global object allocation limit. This feature was 2039 * never enabled in release builds. The allocation limits feature 2040 * was removed in Honeycomb. This method exists for compatibility 2041 * and always returns -1 and has no effect. 2042 * 2043 * @deprecated This method is now obsolete. 2044 */ 2045 @Deprecated setGlobalAllocationLimit(int limit)2046 public static int setGlobalAllocationLimit(int limit) { 2047 return -1; 2048 } 2049 2050 /** 2051 * Dump a list of all currently loaded class to the log file. 2052 * 2053 * @param flags See constants above. 2054 */ printLoadedClasses(int flags)2055 public static void printLoadedClasses(int flags) { 2056 VMDebug.printLoadedClasses(flags); 2057 } 2058 2059 /** 2060 * Get the number of loaded classes. 2061 * @return the number of loaded classes. 2062 */ getLoadedClassCount()2063 public static int getLoadedClassCount() { 2064 return VMDebug.getLoadedClassCount(); 2065 } 2066 2067 /** 2068 * Dump "hprof" data to the specified file. This may cause a GC. 2069 * 2070 * @param fileName Full pathname of output file (e.g. "/sdcard/dump.hprof"). 2071 * @throws UnsupportedOperationException if the VM was built without 2072 * HPROF support. 2073 * @throws IOException if an error occurs while opening or writing files. 2074 */ dumpHprofData(String fileName)2075 public static void dumpHprofData(String fileName) throws IOException { 2076 VMDebug.dumpHprofData(fileName); 2077 } 2078 2079 /** 2080 * Like dumpHprofData(String), but takes an already-opened 2081 * FileDescriptor to which the trace is written. The file name is also 2082 * supplied simply for logging. Makes a dup of the file descriptor. 2083 * 2084 * Primarily for use by the "am" shell command. 2085 * 2086 * @hide 2087 */ dumpHprofData(String fileName, FileDescriptor fd)2088 public static void dumpHprofData(String fileName, FileDescriptor fd) 2089 throws IOException { 2090 VMDebug.dumpHprofData(fileName, fd); 2091 } 2092 2093 /** 2094 * Collect "hprof" and send it to DDMS. This may cause a GC. 2095 * 2096 * @throws UnsupportedOperationException if the VM was built without 2097 * HPROF support. 2098 * @hide 2099 */ dumpHprofDataDdms()2100 public static void dumpHprofDataDdms() { 2101 VMDebug.dumpHprofDataDdms(); 2102 } 2103 2104 /** 2105 * Writes native heap data to the specified file descriptor. 2106 * 2107 * @hide 2108 */ 2109 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) dumpNativeHeap(FileDescriptor fd)2110 public static native void dumpNativeHeap(FileDescriptor fd); 2111 2112 /** 2113 * Writes malloc info data to the specified file descriptor. 2114 * 2115 * @hide 2116 */ dumpNativeMallocInfo(FileDescriptor fd)2117 public static native void dumpNativeMallocInfo(FileDescriptor fd); 2118 2119 /** 2120 * Returns a count of the extant instances of a class. 2121 * 2122 * @hide 2123 */ 2124 @UnsupportedAppUsage countInstancesOfClass(Class cls)2125 public static long countInstancesOfClass(Class cls) { 2126 return VMDebug.countInstancesOfClass(cls, true); 2127 } 2128 2129 /** 2130 * Returns the number of sent transactions from this process. 2131 * @return The number of sent transactions or -1 if it could not read t. 2132 */ getBinderSentTransactions()2133 public static native int getBinderSentTransactions(); 2134 2135 /** 2136 * Returns the number of received transactions from the binder driver. 2137 * @return The number of received transactions or -1 if it could not read the stats. 2138 */ getBinderReceivedTransactions()2139 public static native int getBinderReceivedTransactions(); 2140 2141 /** 2142 * Returns the number of active local Binder objects that exist in the 2143 * current process. 2144 */ getBinderLocalObjectCount()2145 public static final native int getBinderLocalObjectCount(); 2146 2147 /** 2148 * Returns the number of references to remote proxy Binder objects that 2149 * exist in the current process. 2150 */ getBinderProxyObjectCount()2151 public static final native int getBinderProxyObjectCount(); 2152 2153 /** 2154 * Returns the number of death notification links to Binder objects that 2155 * exist in the current process. 2156 */ getBinderDeathObjectCount()2157 public static final native int getBinderDeathObjectCount(); 2158 2159 /** 2160 * Dumps the contents of VM reference tables (e.g. JNI locals and 2161 * globals) to the log file. 2162 * 2163 * @hide 2164 */ 2165 @UnsupportedAppUsage dumpReferenceTables()2166 public static final void dumpReferenceTables() { 2167 VMDebug.dumpReferenceTables(); 2168 } 2169 2170 /** 2171 * API for gathering and querying instruction counts. 2172 * 2173 * Example usage: 2174 * <pre> 2175 * Debug.InstructionCount icount = new Debug.InstructionCount(); 2176 * icount.resetAndStart(); 2177 * [... do lots of stuff ...] 2178 * if (icount.collect()) { 2179 * System.out.println("Total instructions executed: " 2180 * + icount.globalTotal()); 2181 * System.out.println("Method invocations: " 2182 * + icount.globalMethodInvocations()); 2183 * } 2184 * </pre> 2185 * 2186 * @deprecated Instruction counting is no longer supported. 2187 */ 2188 @Deprecated 2189 public static class InstructionCount { InstructionCount()2190 public InstructionCount() { 2191 } 2192 2193 /** 2194 * Reset counters and ensure counts are running. Counts may 2195 * have already been running. 2196 * 2197 * @return true if counting was started 2198 */ resetAndStart()2199 public boolean resetAndStart() { 2200 return false; 2201 } 2202 2203 /** 2204 * Collect instruction counts. May or may not stop the 2205 * counting process. 2206 */ collect()2207 public boolean collect() { 2208 return false; 2209 } 2210 2211 /** 2212 * Return the total number of instructions executed globally (i.e. in 2213 * all threads). 2214 */ globalTotal()2215 public int globalTotal() { 2216 return 0; 2217 } 2218 2219 /** 2220 * Return the total number of method-invocation instructions 2221 * executed globally. 2222 */ globalMethodInvocations()2223 public int globalMethodInvocations() { 2224 return 0; 2225 } 2226 } 2227 2228 /** 2229 * A Map of typed debug properties. 2230 */ 2231 private static final TypedProperties debugProperties; 2232 2233 /* 2234 * Load the debug properties from the standard files into debugProperties. 2235 */ 2236 static { 2237 if (false) { 2238 final String TAG = "DebugProperties"; 2239 final String[] files = { "/system/debug.prop", "/debug.prop", "/data/debug.prop" }; 2240 final TypedProperties tp = new TypedProperties(); 2241 2242 // Read the properties from each of the files, if present. 2243 for (String file : files) { 2244 Reader r; 2245 try { 2246 r = new FileReader(file); 2247 } catch (FileNotFoundException ex) { 2248 // It's ok if a file is missing. 2249 continue; 2250 } 2251 2252 try { 2253 tp.load(r); 2254 } catch (Exception ex) { 2255 throw new RuntimeException("Problem loading " + file, ex); 2256 } finally { 2257 try { r.close()2258 r.close(); 2259 } catch (IOException ex) { 2260 // Ignore this error. 2261 } 2262 } 2263 } 2264 2265 debugProperties = tp.isEmpty() ? null : tp; 2266 } else { 2267 debugProperties = null; 2268 } 2269 } 2270 2271 2272 /** 2273 * Returns true if the type of the field matches the specified class. 2274 * Handles the case where the class is, e.g., java.lang.Boolean, but 2275 * the field is of the primitive "boolean" type. Also handles all of 2276 * the java.lang.Number subclasses. 2277 */ fieldTypeMatches(Field field, Class<?> cl)2278 private static boolean fieldTypeMatches(Field field, Class<?> cl) { 2279 Class<?> fieldClass = field.getType(); 2280 if (fieldClass == cl) { 2281 return true; 2282 } 2283 Field primitiveTypeField; 2284 try { 2285 /* All of the classes we care about (Boolean, Integer, etc.) 2286 * have a Class field called "TYPE" that points to the corresponding 2287 * primitive class. 2288 */ 2289 primitiveTypeField = cl.getField("TYPE"); 2290 } catch (NoSuchFieldException ex) { 2291 return false; 2292 } 2293 try { 2294 return fieldClass == (Class<?>) primitiveTypeField.get(null); 2295 } catch (IllegalAccessException ex) { 2296 return false; 2297 } 2298 } 2299 2300 2301 /** 2302 * Looks up the property that corresponds to the field, and sets the field's value 2303 * if the types match. 2304 */ modifyFieldIfSet(final Field field, final TypedProperties properties, final String propertyName)2305 private static void modifyFieldIfSet(final Field field, final TypedProperties properties, 2306 final String propertyName) { 2307 if (field.getType() == java.lang.String.class) { 2308 int stringInfo = properties.getStringInfo(propertyName); 2309 switch (stringInfo) { 2310 case TypedProperties.STRING_SET: 2311 // Handle as usual below. 2312 break; 2313 case TypedProperties.STRING_NULL: 2314 try { 2315 field.set(null, null); // null object for static fields; null string 2316 } catch (IllegalAccessException ex) { 2317 throw new IllegalArgumentException( 2318 "Cannot set field for " + propertyName, ex); 2319 } 2320 return; 2321 case TypedProperties.STRING_NOT_SET: 2322 return; 2323 case TypedProperties.STRING_TYPE_MISMATCH: 2324 throw new IllegalArgumentException( 2325 "Type of " + propertyName + " " + 2326 " does not match field type (" + field.getType() + ")"); 2327 default: 2328 throw new IllegalStateException( 2329 "Unexpected getStringInfo(" + propertyName + ") return value " + 2330 stringInfo); 2331 } 2332 } 2333 Object value = properties.get(propertyName); 2334 if (value != null) { 2335 if (!fieldTypeMatches(field, value.getClass())) { 2336 throw new IllegalArgumentException( 2337 "Type of " + propertyName + " (" + value.getClass() + ") " + 2338 " does not match field type (" + field.getType() + ")"); 2339 } 2340 try { 2341 field.set(null, value); // null object for static fields 2342 } catch (IllegalAccessException ex) { 2343 throw new IllegalArgumentException( 2344 "Cannot set field for " + propertyName, ex); 2345 } 2346 } 2347 } 2348 2349 2350 /** 2351 * Equivalent to <code>setFieldsOn(cl, false)</code>. 2352 * 2353 * @see #setFieldsOn(Class, boolean) 2354 * 2355 * @hide 2356 */ setFieldsOn(Class<?> cl)2357 public static void setFieldsOn(Class<?> cl) { 2358 setFieldsOn(cl, false); 2359 } 2360 2361 /** 2362 * Reflectively sets static fields of a class based on internal debugging 2363 * properties. This method is a no-op if false is 2364 * false. 2365 * <p> 2366 * <strong>NOTE TO APPLICATION DEVELOPERS</strong>: false will 2367 * always be false in release builds. This API is typically only useful 2368 * for platform developers. 2369 * </p> 2370 * Class setup: define a class whose only fields are non-final, static 2371 * primitive types (except for "char") or Strings. In a static block 2372 * after the field definitions/initializations, pass the class to 2373 * this method, Debug.setFieldsOn(). Example: 2374 * <pre> 2375 * package com.example; 2376 * 2377 * import android.os.Debug; 2378 * 2379 * public class MyDebugVars { 2380 * public static String s = "a string"; 2381 * public static String s2 = "second string"; 2382 * public static String ns = null; 2383 * public static boolean b = false; 2384 * public static int i = 5; 2385 * @Debug.DebugProperty 2386 * public static float f = 0.1f; 2387 * @@Debug.DebugProperty 2388 * public static double d = 0.5d; 2389 * 2390 * // This MUST appear AFTER all fields are defined and initialized! 2391 * static { 2392 * // Sets all the fields 2393 * Debug.setFieldsOn(MyDebugVars.class); 2394 * 2395 * // Sets only the fields annotated with @Debug.DebugProperty 2396 * // Debug.setFieldsOn(MyDebugVars.class, true); 2397 * } 2398 * } 2399 * </pre> 2400 * setFieldsOn() may override the value of any field in the class based 2401 * on internal properties that are fixed at boot time. 2402 * <p> 2403 * These properties are only set during platform debugging, and are not 2404 * meant to be used as a general-purpose properties store. 2405 * 2406 * {@hide} 2407 * 2408 * @param cl The class to (possibly) modify 2409 * @param partial If false, sets all static fields, otherwise, only set 2410 * fields with the {@link android.os.Debug.DebugProperty} 2411 * annotation 2412 * @throws IllegalArgumentException if any fields are final or non-static, 2413 * or if the type of the field does not match the type of 2414 * the internal debugging property value. 2415 */ setFieldsOn(Class<?> cl, boolean partial)2416 public static void setFieldsOn(Class<?> cl, boolean partial) { 2417 if (false) { 2418 if (debugProperties != null) { 2419 /* Only look for fields declared directly by the class, 2420 * so we don't mysteriously change static fields in superclasses. 2421 */ 2422 for (Field field : cl.getDeclaredFields()) { 2423 if (!partial || field.getAnnotation(DebugProperty.class) != null) { 2424 final String propertyName = cl.getName() + "." + field.getName(); 2425 boolean isStatic = Modifier.isStatic(field.getModifiers()); 2426 boolean isFinal = Modifier.isFinal(field.getModifiers()); 2427 2428 if (!isStatic || isFinal) { 2429 throw new IllegalArgumentException(propertyName + 2430 " must be static and non-final"); 2431 } 2432 modifyFieldIfSet(field, debugProperties, propertyName); 2433 } 2434 } 2435 } 2436 } else { 2437 Log.wtf(TAG, 2438 "setFieldsOn(" + (cl == null ? "null" : cl.getName()) + 2439 ") called in non-DEBUG build"); 2440 } 2441 } 2442 2443 /** 2444 * Annotation to put on fields you want to set with 2445 * {@link Debug#setFieldsOn(Class, boolean)}. 2446 * 2447 * @hide 2448 */ 2449 @Target({ ElementType.FIELD }) 2450 @Retention(RetentionPolicy.RUNTIME) 2451 public @interface DebugProperty { 2452 } 2453 2454 /** 2455 * Get a debugging dump of a system service by name. 2456 * 2457 * <p>Most services require the caller to hold android.permission.DUMP. 2458 * 2459 * @param name of the service to dump 2460 * @param fd to write dump output to (usually an output log file) 2461 * @param args to pass to the service's dump method, may be null 2462 * @return true if the service was dumped successfully, false if 2463 * the service could not be found or had an error while dumping 2464 */ dumpService(String name, FileDescriptor fd, String[] args)2465 public static boolean dumpService(String name, FileDescriptor fd, String[] args) { 2466 IBinder service = ServiceManager.getService(name); 2467 if (service == null) { 2468 Log.e(TAG, "Can't find service to dump: " + name); 2469 return false; 2470 } 2471 2472 try { 2473 service.dump(fd, args); 2474 return true; 2475 } catch (RemoteException e) { 2476 Log.e(TAG, "Can't dump service: " + name, e); 2477 return false; 2478 } 2479 } 2480 2481 /** 2482 * Append the Java stack traces of a given native process to a specified file. 2483 * 2484 * @param pid pid to dump. 2485 * @param file path of file to append dump to. 2486 * @param timeoutSecs time to wait in seconds, or 0 to wait forever. 2487 * @hide 2488 */ dumpJavaBacktraceToFileTimeout(int pid, String file, int timeoutSecs)2489 public static native boolean dumpJavaBacktraceToFileTimeout(int pid, String file, 2490 int timeoutSecs); 2491 2492 /** 2493 * Append the native stack traces of a given process to a specified file. 2494 * 2495 * @param pid pid to dump. 2496 * @param file path of file to append dump to. 2497 * @param timeoutSecs time to wait in seconds, or 0 to wait forever. 2498 * @hide 2499 */ dumpNativeBacktraceToFileTimeout(int pid, String file, int timeoutSecs)2500 public static native boolean dumpNativeBacktraceToFileTimeout(int pid, String file, 2501 int timeoutSecs); 2502 2503 /** 2504 * Get description of unreachable native memory. 2505 * @param limit the number of leaks to provide info on, 0 to only get a summary. 2506 * @param contents true to include a hex dump of the contents of unreachable memory. 2507 * @return the String containing a description of unreachable memory. 2508 * @hide */ getUnreachableMemory(int limit, boolean contents)2509 public static native String getUnreachableMemory(int limit, boolean contents); 2510 2511 /** 2512 * Return a String describing the calling method and location at a particular stack depth. 2513 * @param callStack the Thread stack 2514 * @param depth the depth of stack to return information for. 2515 * @return the String describing the caller at that depth. 2516 */ getCaller(StackTraceElement callStack[], int depth)2517 private static String getCaller(StackTraceElement callStack[], int depth) { 2518 // callStack[4] is the caller of the method that called getCallers() 2519 if (4 + depth >= callStack.length) { 2520 return "<bottom of call stack>"; 2521 } 2522 StackTraceElement caller = callStack[4 + depth]; 2523 return caller.getClassName() + "." + caller.getMethodName() + ":" + caller.getLineNumber(); 2524 } 2525 2526 /** 2527 * Return a string consisting of methods and locations at multiple call stack levels. 2528 * @param depth the number of levels to return, starting with the immediate caller. 2529 * @return a string describing the call stack. 2530 * {@hide} 2531 */ 2532 @UnsupportedAppUsage getCallers(final int depth)2533 public static String getCallers(final int depth) { 2534 final StackTraceElement[] callStack = Thread.currentThread().getStackTrace(); 2535 StringBuilder sb = new StringBuilder(); 2536 for (int i = 0; i < depth; i++) { 2537 sb.append(getCaller(callStack, i)).append(" "); 2538 } 2539 return sb.toString(); 2540 } 2541 2542 /** 2543 * Return a string consisting of methods and locations at multiple call stack levels. 2544 * @param depth the number of levels to return, starting with the immediate caller. 2545 * @return a string describing the call stack. 2546 * {@hide} 2547 */ getCallers(final int start, int depth)2548 public static String getCallers(final int start, int depth) { 2549 final StackTraceElement[] callStack = Thread.currentThread().getStackTrace(); 2550 StringBuilder sb = new StringBuilder(); 2551 depth += start; 2552 for (int i = start; i < depth; i++) { 2553 sb.append(getCaller(callStack, i)).append(" "); 2554 } 2555 return sb.toString(); 2556 } 2557 2558 /** 2559 * Like {@link #getCallers(int)}, but each location is append to the string 2560 * as a new line with <var>linePrefix</var> in front of it. 2561 * @param depth the number of levels to return, starting with the immediate caller. 2562 * @param linePrefix prefix to put in front of each location. 2563 * @return a string describing the call stack. 2564 * {@hide} 2565 */ getCallers(final int depth, String linePrefix)2566 public static String getCallers(final int depth, String linePrefix) { 2567 final StackTraceElement[] callStack = Thread.currentThread().getStackTrace(); 2568 StringBuilder sb = new StringBuilder(); 2569 for (int i = 0; i < depth; i++) { 2570 sb.append(linePrefix).append(getCaller(callStack, i)).append("\n"); 2571 } 2572 return sb.toString(); 2573 } 2574 2575 /** 2576 * @return a String describing the immediate caller of the calling method. 2577 * {@hide} 2578 */ 2579 @UnsupportedAppUsage getCaller()2580 public static String getCaller() { 2581 return getCaller(Thread.currentThread().getStackTrace(), 0); 2582 } 2583 2584 /** 2585 * Attach a library as a jvmti agent to the current runtime, with the given classloader 2586 * determining the library search path. 2587 * <p> 2588 * Note: agents may only be attached to debuggable apps. Otherwise, this function will 2589 * throw a SecurityException. 2590 * 2591 * @param library the library containing the agent. 2592 * @param options the options passed to the agent. 2593 * @param classLoader the classloader determining the library search path. 2594 * 2595 * @throws IOException if the agent could not be attached. 2596 * @throws SecurityException if the app is not debuggable. 2597 */ attachJvmtiAgent(@onNull String library, @Nullable String options, @Nullable ClassLoader classLoader)2598 public static void attachJvmtiAgent(@NonNull String library, @Nullable String options, 2599 @Nullable ClassLoader classLoader) throws IOException { 2600 Preconditions.checkNotNull(library); 2601 Preconditions.checkArgument(!library.contains("=")); 2602 2603 if (options == null) { 2604 VMDebug.attachAgent(library, classLoader); 2605 } else { 2606 VMDebug.attachAgent(library + "=" + options, classLoader); 2607 } 2608 } 2609 2610 /** 2611 * Return the current free ZRAM usage in kilobytes. 2612 * 2613 * @hide 2614 */ getZramFreeKb()2615 public static native long getZramFreeKb(); 2616 2617 /** 2618 * Return total memory size in kilobytes for exported DMA-BUFs or -1 if 2619 * the DMA-BUF sysfs stats at /sys/kernel/dmabuf/buffers could not be read. 2620 * 2621 * @hide 2622 */ getDmabufTotalExportedKb()2623 public static native long getDmabufTotalExportedKb(); 2624 2625 /** 2626 * Return total memory size in kilobytes for DMA-BUFs exported from the DMA-BUF 2627 * heaps frameworks or -1 in the case of an error. 2628 * 2629 * @hide 2630 */ getDmabufHeapTotalExportedKb()2631 public static native long getDmabufHeapTotalExportedKb(); 2632 2633 /** 2634 * Return memory size in kilobytes allocated for ION heaps or -1 if 2635 * /sys/kernel/ion/total_heaps_kb could not be read. 2636 * 2637 * @hide 2638 */ getIonHeapsSizeKb()2639 public static native long getIonHeapsSizeKb(); 2640 2641 /** 2642 * Return memory size in kilobytes allocated for DMA-BUF heap pools or -1 if 2643 * /sys/kernel/dma_heap/total_pools_kb could not be read. 2644 * 2645 * @hide 2646 */ getDmabufHeapPoolsSizeKb()2647 public static native long getDmabufHeapPoolsSizeKb(); 2648 2649 /** 2650 * Return memory size in kilobytes allocated for ION pools or -1 if 2651 * /sys/kernel/ion/total_pools_kb could not be read. 2652 * 2653 * @hide 2654 */ getIonPoolsSizeKb()2655 public static native long getIonPoolsSizeKb(); 2656 2657 /** 2658 * Returns the global total GPU-private memory in kB or -1 on error. 2659 * 2660 * @hide 2661 */ getGpuPrivateMemoryKb()2662 public static native long getGpuPrivateMemoryKb(); 2663 2664 /** 2665 * Return DMA-BUF memory mapped by processes in kB. 2666 * Notes: 2667 * * Warning: Might impact performance as it reads /proc/<pid>/maps files for each process. 2668 * 2669 * @hide 2670 */ getDmabufMappedSizeKb()2671 public static native long getDmabufMappedSizeKb(); 2672 2673 /** 2674 * Return memory size in kilobytes used by GPU. 2675 * 2676 * @hide 2677 */ getGpuTotalUsageKb()2678 public static native long getGpuTotalUsageKb(); 2679 2680 /** 2681 * Return whether virtually-mapped kernel stacks are enabled (CONFIG_VMAP_STACK). 2682 * Note: caller needs config_gz read sepolicy permission 2683 * 2684 * @hide 2685 */ isVmapStack()2686 public static native boolean isVmapStack(); 2687 } 2688