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