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