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 dalvik.system; 18 19 import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; 20 21 import android.annotation.SystemApi; 22 import android.compat.annotation.UnsupportedAppUsage; 23 24 import java.io.FileDescriptor; 25 import java.io.IOException; 26 import java.util.HashMap; 27 import java.util.Map; 28 29 import dalvik.annotation.optimization.FastNative; 30 31 /** 32 * Provides access to some VM-specific debug features. Though this class and 33 * many of its members are public, this class is meant to be wrapped in a more 34 * friendly way for use by application developers. On the Android platform, the 35 * recommended way to access this functionality is through the class 36 * <code>android.os.Debug</code>. 37 * 38 * @hide 39 */ 40 @SystemApi(client = MODULE_LIBRARIES) 41 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 42 public final class VMDebug { 43 /** 44 * flag for startMethodTracing(), which adds the results from 45 * startAllocCounting to the trace key file. 46 * 47 * @hide 48 */ 49 @SystemApi(client = MODULE_LIBRARIES) 50 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 51 // Must match android.os.Debug.TRACE_COUNT_ALLOCS. 52 public static final int TRACE_COUNT_ALLOCS = 1; 53 54 /* constants for getAllocCount */ 55 private static final int KIND_ALLOCATED_OBJECTS = 1<<0; 56 private static final int KIND_ALLOCATED_BYTES = 1<<1; 57 private static final int KIND_FREED_OBJECTS = 1<<2; 58 private static final int KIND_FREED_BYTES = 1<<3; 59 private static final int KIND_GC_INVOCATIONS = 1<<4; 60 private static final int KIND_CLASS_INIT_COUNT = 1<<5; 61 private static final int KIND_CLASS_INIT_TIME = 1<<6; 62 private static final int KIND_EXT_ALLOCATED_OBJECTS = 1<<12; 63 private static final int KIND_EXT_ALLOCATED_BYTES = 1<<13; 64 private static final int KIND_EXT_FREED_OBJECTS = 1<<14; 65 private static final int KIND_EXT_FREED_BYTES = 1<<15; 66 67 /** 68 * Constant for {@link #getAllocCount(int)} 69 * to get the number of all allocated objects. 70 * 71 * @hide 72 */ 73 @SystemApi(client = MODULE_LIBRARIES) 74 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 75 public static final int KIND_GLOBAL_ALLOCATED_OBJECTS = 76 KIND_ALLOCATED_OBJECTS; 77 78 /** 79 * Constant for {@link #getAllocCount(int)} 80 * to get the cumulative size of all objects allocated. 81 * 82 * @hide 83 */ 84 @SystemApi(client = MODULE_LIBRARIES) 85 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 86 public static final int KIND_GLOBAL_ALLOCATED_BYTES = 87 KIND_ALLOCATED_BYTES; 88 89 /** 90 * Constant for {@link #getAllocCount(int)} 91 * to get the number of freed objects. 92 * 93 * @hide 94 */ 95 @SystemApi(client = MODULE_LIBRARIES) 96 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 97 public static final int KIND_GLOBAL_FREED_OBJECTS = 98 KIND_FREED_OBJECTS; 99 100 /** 101 * Constant for {@link #getAllocCount(int)} 102 * to get the cumulative size of all freed objects. 103 * 104 * @hide 105 */ 106 @SystemApi(client = MODULE_LIBRARIES) 107 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 108 public static final int KIND_GLOBAL_FREED_BYTES = 109 KIND_FREED_BYTES; 110 111 /** 112 * Constant for {@link #getAllocCount(int)} 113 * to get the number of times an allocation triggered a blocking GC. 114 * 115 * @hide 116 */ 117 @SystemApi(client = MODULE_LIBRARIES) 118 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 119 public static final int KIND_GLOBAL_GC_INVOCATIONS = 120 KIND_GC_INVOCATIONS; 121 122 /** 123 * Constant for {@link #getAllocCount(int)} 124 * to get the number of initialized classes. 125 * 126 * @hide 127 */ 128 @SystemApi(client = MODULE_LIBRARIES) 129 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 130 public static final int KIND_GLOBAL_CLASS_INIT_COUNT = 131 KIND_CLASS_INIT_COUNT; 132 133 /** 134 * Constant for {@link #getAllocCount(int)} 135 * to get the cumulative time spent in class initialization. 136 * 137 * @hide 138 */ 139 @SystemApi(client = MODULE_LIBRARIES) 140 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 141 public static final int KIND_GLOBAL_CLASS_INIT_TIME = 142 KIND_CLASS_INIT_TIME; 143 144 /** 145 * Constant for {@link #getAllocCount(int)} 146 * to get the number of all allocated objects for current thread. 147 * 148 * @hide 149 */ 150 @SystemApi(client = MODULE_LIBRARIES) 151 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 152 public static final int KIND_THREAD_ALLOCATED_OBJECTS = 153 KIND_ALLOCATED_OBJECTS << 16; 154 155 /** 156 * Constant for {@link #getAllocCount(int)} 157 * to get the cumulative size of all objects allocated for current thread. 158 * 159 * @hide 160 */ 161 @SystemApi(client = MODULE_LIBRARIES) 162 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 163 public static final int KIND_THREAD_ALLOCATED_BYTES = 164 KIND_ALLOCATED_BYTES << 16; 165 166 /** 167 * Constant for {@link #getAllocCount(int)} 168 * to get the number of times an allocation triggered a blocking GC for current thread. 169 * 170 * @hide 171 */ 172 @SystemApi(client = MODULE_LIBRARIES) 173 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 174 public static final int KIND_THREAD_GC_INVOCATIONS = 175 KIND_GC_INVOCATIONS << 16; 176 177 /** 178 * Constant for {@link #getAllocCount(int)} to get all possible stats. 179 * 180 * @hide 181 */ 182 @SystemApi(client = MODULE_LIBRARIES) 183 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 184 public static final int KIND_ALL_COUNTS = 0xffffffff; 185 186 /* all methods are static */ VMDebug()187 private VMDebug() {} 188 189 /** 190 * Returns the time since the last known debugger activity. 191 * 192 * @return the time in milliseconds, or -1 if the debugger is not connected 193 * 194 * @hide 195 */ 196 @SystemApi(client = MODULE_LIBRARIES) 197 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 198 @FastNative lastDebuggerActivity()199 public static native long lastDebuggerActivity(); 200 201 /** 202 * Determines if debugging is enabled in this VM. If debugging is not 203 * enabled, a debugger cannot be attached. 204 * 205 * @return true if debugging is enabled 206 * 207 * @hide 208 */ 209 @SystemApi(client = MODULE_LIBRARIES) 210 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 211 @FastNative isDebuggingEnabled()212 public static native boolean isDebuggingEnabled(); 213 214 /** 215 * Determines if a debugger is currently attached. 216 * 217 * @return true if (and only if) a debugger is connected 218 * 219 * @hide 220 */ 221 @UnsupportedAppUsage 222 @SystemApi(client = MODULE_LIBRARIES) 223 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 224 @FastNative isDebuggerConnected()225 public static native boolean isDebuggerConnected(); 226 227 /** 228 * Returns an array of strings that identify VM features. This is 229 * used by DDMS to determine what sorts of operations the VM can 230 * perform. 231 * 232 * @return array of strings identifying VM features 233 * 234 * @hide 235 */ 236 @SystemApi(client = MODULE_LIBRARIES) 237 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) getVmFeatureList()238 public static native String[] getVmFeatureList(); 239 240 /** 241 * Start method tracing, specifying a file name as well as a default 242 * buffer size. See <a 243 * href="{@docRoot}guide/developing/tools/traceview.html"> Running the 244 * Traceview Debugging Program</a> for information about reading 245 * trace files. 246 * 247 * <p>You can use either a fully qualified path and 248 * name, or just a name. If only a name is specified, the file will 249 * be created under the /sdcard/ directory. If a name is not given, 250 * the default is /sdcard/dmtrace.trace.</p> 251 * 252 * @param traceFileName name to give the trace file 253 * @param bufferSize the maximum size of both files combined. If passed 254 * as {@code 0}, it defaults to 8MB. 255 * @param flags flags to control method tracing. The only one that 256 * is currently defined is {@link #TRACE_COUNT_ALLOCS}. 257 * @param samplingEnabled if true, sample profiling is enabled. Otherwise, 258 * method instrumentation is used. 259 * @param intervalUs the time between samples in microseconds when 260 * sampling is enabled. 261 * 262 * @hide 263 */ 264 @SystemApi(client = MODULE_LIBRARIES) 265 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) startMethodTracing(String traceFileName, int bufferSize, int flags, boolean samplingEnabled, int intervalUs)266 public static void startMethodTracing(String traceFileName, int bufferSize, int flags, boolean samplingEnabled, int intervalUs) { 267 startMethodTracingFilename(traceFileName, checkBufferSize(bufferSize), flags, samplingEnabled, intervalUs); 268 } 269 270 /** 271 * Like {@link #startMethodTracing(String, int, int)}, but taking an already-opened 272 * {@code FileDescriptor} in which the trace is written. The file name is also 273 * supplied simply for logging. Makes a dup of the file descriptor. 274 * Streams tracing data to the file if streamingOutput is true. 275 * 276 * @param traceFileName name to give the trace file 277 * @param fd already opened {@code FileDescriptor} in which trace is written 278 * @param bufferSize the maximum size of both files combined. If passed 279 * as {@code 0}, it defaults to 8MB. 280 * @param flags flags to control method tracing. The only one that 281 * is currently defined is {@link #TRACE_COUNT_ALLOCS}. 282 * @param samplingEnabled if true, sample profiling is enabled. Otherwise, 283 * method instrumentation is used. 284 * @param intervalUs the time between samples in microseconds when 285 * sampling is enabled. 286 * @param streamingOutput streams tracing data to the duped {@code fd} file descriptor 287 * if {@code streamingOutput} is {@code true}. 288 * 289 * @hide 290 */ 291 @SystemApi(client = MODULE_LIBRARIES) 292 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) startMethodTracing(String traceFileName, FileDescriptor fd, int bufferSize, int flags, boolean samplingEnabled, int intervalUs, boolean streamingOutput)293 public static void startMethodTracing(String traceFileName, FileDescriptor fd, int bufferSize, 294 int flags, boolean samplingEnabled, int intervalUs, 295 boolean streamingOutput) { 296 if (fd == null) { 297 throw new NullPointerException("fd == null"); 298 } 299 startMethodTracingFd(traceFileName, fd.getInt$(), checkBufferSize(bufferSize), flags, 300 samplingEnabled, intervalUs, streamingOutput); 301 } 302 303 /** 304 * Starts method tracing without a backing file. When {@link #stopMethodTracing()} 305 * is called, the result is sent directly to DDMS. (If DDMS is not 306 * attached when tracing ends, the profiling data will be discarded.) 307 * 308 * @param bufferSize the maximum size of both files combined. If passed 309 * as {@code 0}, it defaults to 8MB. 310 * @param flags flags to control method tracing. The only one that 311 * is currently defined is {@link #TRACE_COUNT_ALLOCS}. 312 * @param samplingEnabled if true, sample profiling is enabled. Otherwise, 313 * method instrumentation is used. 314 * @param intervalUs the time between samples in microseconds when 315 * sampling is enabled. 316 * 317 * @hide 318 */ 319 @SystemApi(client = MODULE_LIBRARIES) 320 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) startMethodTracingDdms(int bufferSize, int flags, boolean samplingEnabled, int intervalUs)321 public static void startMethodTracingDdms(int bufferSize, int flags, boolean samplingEnabled, int intervalUs) { 322 startMethodTracingDdmsImpl(checkBufferSize(bufferSize), flags, samplingEnabled, intervalUs); 323 } 324 checkBufferSize(int bufferSize)325 private static int checkBufferSize(int bufferSize) { 326 if (bufferSize == 0) { 327 // Default to 8MB per the documentation. 328 bufferSize = 8 * 1024 * 1024; 329 } 330 if (bufferSize < 1024) { 331 throw new IllegalArgumentException("buffer size < 1024: " + bufferSize); 332 } 333 return bufferSize; 334 } 335 startMethodTracingDdmsImpl(int bufferSize, int flags, boolean samplingEnabled, int intervalUs)336 private static native void startMethodTracingDdmsImpl(int bufferSize, int flags, boolean samplingEnabled, int intervalUs); startMethodTracingFd(String traceFileName, int fd, int bufferSize, int flags, boolean samplingEnabled, int intervalUs, boolean streamingOutput)337 private static native void startMethodTracingFd(String traceFileName, int fd, int bufferSize, 338 int flags, boolean samplingEnabled, int intervalUs, boolean streamingOutput); startMethodTracingFilename(String traceFileName, int bufferSize, int flags, boolean samplingEnabled, int intervalUs)339 private static native void startMethodTracingFilename(String traceFileName, int bufferSize, int flags, boolean samplingEnabled, int intervalUs); 340 341 /** 342 * Determine whether method tracing is currently active and what type is 343 * active. 344 * 345 * @hide 346 */ 347 @SystemApi(client = MODULE_LIBRARIES) 348 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) getMethodTracingMode()349 public static native int getMethodTracingMode(); 350 351 /** 352 * Stops method tracing. 353 * 354 * @hide 355 */ 356 @SystemApi(client = MODULE_LIBRARIES) 357 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) stopMethodTracing()358 public static native void stopMethodTracing(); 359 360 /** 361 * Get an indication of thread CPU usage. The value returned indicates the 362 * amount of time that the current thread has spent executing code or 363 * waiting for certain types of I/O. 364 * <p> 365 * The time is expressed in nanoseconds, and is only meaningful when 366 * compared to the result from an earlier call. Note that nanosecond 367 * resolution does not imply nanosecond accuracy. 368 * 369 * @return the CPU usage. A value of -1 means the system does not support 370 * this feature. 371 * 372 * @hide 373 */ 374 @SystemApi(client = MODULE_LIBRARIES) 375 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 376 @FastNative threadCpuTimeNanos()377 public static native long threadCpuTimeNanos(); 378 379 /** 380 * Starts counting the number and aggregate size of memory allocations. 381 * 382 * @hide 383 */ 384 @SystemApi(client = MODULE_LIBRARIES) 385 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) startAllocCounting()386 public static native void startAllocCounting(); 387 388 /** 389 * Stops counting the number and aggregate size of memory allocations. 390 * 391 * @hide 392 */ 393 @SystemApi(client = MODULE_LIBRARIES) 394 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) stopAllocCounting()395 public static native void stopAllocCounting(); 396 397 /** 398 * Returns information on the number of objects allocated by the runtime between a 399 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}. 400 * 401 * @param kind either {@code KIND_GLOBAL_*} or {@code KIND_THREAD_*}. 402 * 403 * @hide 404 */ 405 @SystemApi(client = MODULE_LIBRARIES) 406 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) getAllocCount(int kind)407 public static native int getAllocCount(int kind); 408 409 /** 410 * Resets counting the number and aggregate size of memory allocations for the given kinds. 411 * 412 * @param kinds a union of {@code KIND_GLOBAL_*} and {@code KIND_THREAD_*}. 413 * 414 * @hide 415 */ 416 @SystemApi(client = MODULE_LIBRARIES) 417 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) resetAllocCount(int kinds)418 public static native void resetAllocCount(int kinds); 419 420 /** 421 * This method exists for binary compatibility. It was part of 422 * the allocation limits API which was removed in Android 3.0 (Honeycomb). 423 * 424 * @hide 425 */ 426 @Deprecated setAllocationLimit(int limit)427 public static int setAllocationLimit(int limit) { 428 return -1; 429 } 430 431 /** 432 * This method exists for binary compatibility. It was part of 433 * the allocation limits API which was removed in Android 3.0 (Honeycomb). 434 * 435 * @hide 436 */ 437 @Deprecated setGlobalAllocationLimit(int limit)438 public static int setGlobalAllocationLimit(int limit) { 439 return -1; 440 } 441 442 /** 443 * Count the number of instructions executed between two points. 444 * 445 * @hide 446 */ 447 @Deprecated startInstructionCounting()448 public static void startInstructionCounting() {} 449 450 /** 451 * 452 * @hide 453 */ 454 @Deprecated stopInstructionCounting()455 public static void stopInstructionCounting() {} 456 457 /** 458 * 459 * @hide 460 */ 461 @Deprecated getInstructionCount(int[] counts)462 public static void getInstructionCount(int[] counts) {} 463 464 /** 465 * 466 * @hide 467 */ 468 @Deprecated resetInstructionCount()469 public static void resetInstructionCount() {} 470 471 /** 472 * Dumps a list of loaded class to the log file. 473 * 474 * @param flags a union of {@link android.os.Debug.SHOW_FULL_DETAIL}, 475 * {@link android.os.Debug.SHOW_CLASSLOADER}, and {@link android.os.Debug.SHOW_INITIALIZED}. 476 * 477 * @hide 478 */ 479 @SystemApi(client = MODULE_LIBRARIES) 480 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 481 @FastNative printLoadedClasses(int flags)482 public static native void printLoadedClasses(int flags); 483 484 /** 485 * Gets the number of loaded classes. 486 * 487 * @return the number of loaded classes 488 * 489 * @hide 490 */ 491 @SystemApi(client = MODULE_LIBRARIES) 492 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) 493 @FastNative getLoadedClassCount()494 public static native int getLoadedClassCount(); 495 496 /** 497 * Dumps "hprof" data to the specified file. This may cause a GC. 498 * 499 * The VM may create a temporary file in the same directory. 500 * 501 * @param filename Full pathname of output file (e.g. "/sdcard/dump.hprof"). 502 * @throws UnsupportedOperationException if the VM was built without 503 * HPROF support. 504 * @throws IOException if an error occurs while opening or writing files. 505 * 506 * @hide 507 */ 508 @SystemApi(client = MODULE_LIBRARIES) 509 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) dumpHprofData(String filename)510 public static void dumpHprofData(String filename) throws IOException { 511 if (filename == null) { 512 throw new NullPointerException("filename == null"); 513 } 514 dumpHprofData(filename, null); 515 } 516 517 /** 518 * Collects "hprof" heap data and sends it to DDMS. This may cause a GC. 519 * 520 * @throws UnsupportedOperationException if the VM was built without 521 * HPROF support. 522 * 523 * @hide 524 */ 525 @SystemApi(client = MODULE_LIBRARIES) 526 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) dumpHprofDataDdms()527 public static native void dumpHprofDataDdms(); 528 529 /** 530 * Dumps "hprof" heap data to a file, by name or descriptor. 531 * 532 * @param fileName Name of output file. If fd is non-null, the 533 * file name is only used in log messages (and may be null). 534 * @param fd Descriptor of open file that will receive the output. 535 * If this is null, the fileName is used instead. 536 * @throws {@link IOException} if an error occurs while opening or writing files. 537 * 538 * @hide 539 */ 540 @SystemApi(client = MODULE_LIBRARIES) 541 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) dumpHprofData(String fileName, FileDescriptor fd)542 public static void dumpHprofData(String fileName, FileDescriptor fd) 543 throws IOException { 544 dumpHprofData(fileName, fd != null ? fd.getInt$() : -1); 545 } 546 dumpHprofData(String fileName, int fd)547 private static native void dumpHprofData(String fileName, int fd) 548 throws IOException; 549 550 /** 551 * Dumps the contents of the VM reference tables (e.g. JNI locals and 552 * globals) to the log file. 553 * 554 * @hide 555 */ 556 @UnsupportedAppUsage 557 @SystemApi(client = MODULE_LIBRARIES) 558 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) dumpReferenceTables()559 public static native void dumpReferenceTables(); 560 561 /** 562 * Counts the instances of a class. 563 * It is the caller's responsibility to do GC if they don't want unreachable 564 * objects to get counted. 565 * 566 * @param klass the class to be counted. 567 * @param assignable if true, any instance whose class is assignable to 568 * {@code klass}, as defined by {@link Class#isAssignableFrom}, 569 * is counted. If false, only instances whose class is 570 * equal to {@code klass} are counted. 571 * @return the number of matching instances. 572 * 573 * @hide 574 */ 575 @SystemApi(client = MODULE_LIBRARIES) 576 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) countInstancesOfClass(Class klass, boolean assignable)577 public static native long countInstancesOfClass(Class klass, boolean assignable); 578 579 /** 580 * Counts the instances of classes. 581 * It is the caller's responsibility to do GC if they don't want unreachable 582 * objects to get counted. 583 * 584 * @param classes the classes to be counted. 585 * @param assignable if true, any instance whose class is assignable to 586 * {@code classes[i]}, as defined by {@link Class#isAssignableFrom}, 587 * is counted. If false, only instances whose class is 588 * equal to {@code classes[i]} are counted. 589 * @return an array containing the number of matching instances. The value 590 * for index {@code i} is the number of instances of 591 * the class {@code classes[i]} 592 * 593 * @hide 594 */ 595 @SystemApi(client = MODULE_LIBRARIES) 596 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) countInstancesOfClasses(Class[] classes, boolean assignable)597 public static native long[] countInstancesOfClasses(Class[] classes, boolean assignable); 598 599 /** 600 * Gets instances of classes on the Java heap. 601 * It is the caller's responsibility to do GC if they don't want unreachable 602 * objects to be included. 603 * 604 * @param classes the classes to get instances of. 605 * @param assignable if true, any instance whose class is assignable to 606 * {@code classes[i]}, as defined by {@link Class#isAssignableFrom}, 607 * is included. If false, only instances whose class is 608 * equal to {@code classes[i]} are included. 609 * @return an array containing the list of matching instances. The value 610 * for index {@code i} is an array containing the instances 611 * of the class {@code classes[i]} 612 * 613 * @hide 614 */ getInstancesOfClasses(Class[] classes, boolean assignable)615 public static native Object[][] getInstancesOfClasses(Class[] classes, boolean assignable); 616 617 /* Map from the names of the runtime stats supported by getRuntimeStat() to their IDs */ 618 private static final HashMap<String, Integer> runtimeStatsMap = new HashMap<>(); 619 620 static { 621 runtimeStatsMap.put("art.gc.gc-count", 0); 622 runtimeStatsMap.put("art.gc.gc-time", 1); 623 runtimeStatsMap.put("art.gc.bytes-allocated", 2); 624 runtimeStatsMap.put("art.gc.bytes-freed", 3); 625 runtimeStatsMap.put("art.gc.blocking-gc-count", 4); 626 runtimeStatsMap.put("art.gc.blocking-gc-time", 5); 627 runtimeStatsMap.put("art.gc.gc-count-rate-histogram", 6); 628 runtimeStatsMap.put("art.gc.blocking-gc-count-rate-histogram", 7); 629 runtimeStatsMap.put("art.gc.objects-allocated", 8); 630 runtimeStatsMap.put("art.gc.total-time-waiting-for-gc", 9); 631 } 632 633 /** 634 * Returns the value of a particular runtime statistic or {@code null} if no 635 * such runtime statistic exists. 636 * 637 * @param statName the name of the runtime statistic to look up. 638 * 639 * @return the value of the runtime statistic. 640 * 641 * @hide 642 */ 643 @SystemApi(client = MODULE_LIBRARIES) 644 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) getRuntimeStat(String statName)645 public static String getRuntimeStat(String statName) { 646 if (statName == null) { 647 throw new NullPointerException("statName == null"); 648 } 649 Integer statId = runtimeStatsMap.get(statName); 650 if (statId != null) { 651 return getRuntimeStatInternal(statId); 652 } 653 return null; 654 } 655 656 /** 657 * Returns a map of the names/values of the runtime statistics 658 * that {@link #getRuntimeStat()} supports. 659 * 660 * @return a map of the names/values of the supported runtime statistics. 661 * 662 * @hide 663 */ 664 @SystemApi(client = MODULE_LIBRARIES) 665 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) getRuntimeStats()666 public static Map<String, String> getRuntimeStats() { 667 HashMap<String, String> map = new HashMap<>(); 668 String[] values = getRuntimeStatsInternal(); 669 for (String name : runtimeStatsMap.keySet()) { 670 int id = runtimeStatsMap.get(name); 671 String value = values[id]; 672 map.put(name, value); 673 } 674 return map; 675 } 676 getRuntimeStatInternal(int statId)677 private static native String getRuntimeStatInternal(int statId); getRuntimeStatsInternal()678 private static native String[] getRuntimeStatsInternal(); 679 680 /** 681 * Attaches an agent to the VM. 682 * 683 * @param agent The path to the agent .so file plus optional agent arguments. 684 * @param classLoader The classloader to use as a loading context. 685 * 686 * @throws IOException if an error occurs while opening {@code agent} file. 687 * 688 * @hide 689 */ 690 @SystemApi(client = MODULE_LIBRARIES) 691 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) attachAgent(String agent, ClassLoader classLoader)692 public static void attachAgent(String agent, ClassLoader classLoader) throws IOException { 693 nativeAttachAgent(agent, classLoader); 694 } 695 nativeAttachAgent(String agent, ClassLoader classLoader)696 private static native void nativeAttachAgent(String agent, ClassLoader classLoader) 697 throws IOException; 698 699 /** 700 * Exempts a class from any future non-SDK API access checks. 701 * Methods declared in the class will be allowed to perform 702 * reflection/JNI against the framework completely unrestricted. 703 * Note that this does not affect uses of non-SDK APIs that the class links against. 704 * Note that this does not affect methods declared outside this class, e.g. 705 * inherited from a superclass or an implemented interface. 706 * 707 * @param klass The class whose methods should be exempted. 708 * 709 * @hide 710 */ 711 @UnsupportedAppUsage allowHiddenApiReflectionFrom(Class<?> klass)712 public static native void allowHiddenApiReflectionFrom(Class<?> klass); 713 714 /** 715 * Sets the number of frames recorded for allocation tracking. 716 * 717 * @param stackDepth The number of frames captured for each stack trace. 718 * 719 * @hide 720 */ 721 @SystemApi(client = MODULE_LIBRARIES) 722 @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE) setAllocTrackerStackDepth(int stackDepth)723 public static native void setAllocTrackerStackDepth(int stackDepth); 724 } 725