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