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