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