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