blob: e58744bfd90562854457b62459ff07003ea302dc [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.os;
18
Dianne Hackborn8c841092013-06-24 13:46:13 -070019import com.android.internal.util.FastPrintWriter;
Dave Bort1ce5bd32009-04-22 17:36:56 -070020import com.android.internal.util.TypedProperties;
21
Dave Bort1ce5bd32009-04-22 17:36:56 -070022import android.util.Log;
23
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070024import java.io.FileDescriptor;
Dave Bort1ce5bd32009-04-22 17:36:56 -070025import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import java.io.FileOutputStream;
Dave Bort1ce5bd32009-04-22 17:36:56 -070027import java.io.FileReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import java.io.PrintWriter;
Dave Bort1ce5bd32009-04-22 17:36:56 -070030import java.io.Reader;
31import java.lang.reflect.Field;
32import java.lang.reflect.Modifier;
Romain Guyc4b11a72009-05-13 15:46:37 -070033import java.lang.annotation.Target;
34import java.lang.annotation.ElementType;
35import java.lang.annotation.Retention;
36import java.lang.annotation.RetentionPolicy;
Richard Uhler350e6dc2015-05-18 10:48:52 -070037import java.util.HashMap;
Hiroshi Yamauchi8b5a293d2015-04-02 12:26:10 -070038import java.util.Map;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039
40import org.apache.harmony.dalvik.ddmc.Chunk;
41import org.apache.harmony.dalvik.ddmc.ChunkHandler;
42import org.apache.harmony.dalvik.ddmc.DdmServer;
43
Dan Bornstein9f315542010-11-19 18:12:55 -080044import dalvik.bytecode.OpcodeInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import dalvik.system.VMDebug;
46
47
48/**
Ian Rogersfe067a42013-02-22 19:59:23 -080049 * Provides various debugging methods for Android applications, including
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050 * tracing and allocation counts.
51 * <p><strong>Logging Trace Files</strong></p>
52 * <p>Debug can create log files that give details about an application, such as
53 * a call stack and start/stop times for any running methods. See <a
54href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
55 * information about reading trace files. To start logging trace files, call one
56 * of the startMethodTracing() methods. To stop tracing, call
57 * {@link #stopMethodTracing()}.
58 */
59public final class Debug
60{
Dan Egnor3eda9792010-03-05 13:28:36 -080061 private static final String TAG = "Debug";
62
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 /**
64 * Flags for startMethodTracing(). These can be ORed together.
65 *
66 * TRACE_COUNT_ALLOCS adds the results from startAllocCounting to the
67 * trace key file.
Hiroshi Yamauchi172da262015-03-04 12:29:19 -080068 *
69 * @deprecated Accurate counting is a burden on the runtime and may be removed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -080071 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072 public static final int TRACE_COUNT_ALLOCS = VMDebug.TRACE_COUNT_ALLOCS;
73
74 /**
75 * Flags for printLoadedClasses(). Default behavior is to only show
76 * the class name.
77 */
78 public static final int SHOW_FULL_DETAIL = 1;
79 public static final int SHOW_CLASSLOADER = (1 << 1);
80 public static final int SHOW_INITIALIZED = (1 << 2);
81
82 // set/cleared by waitForDebugger()
83 private static volatile boolean mWaiting = false;
84
85 private Debug() {}
86
87 /*
88 * How long to wait for the debugger to finish sending requests. I've
89 * seen this hit 800msec on the device while waiting for a response
90 * to travel over USB and get processed, so we take that and add
91 * half a second.
92 */
93 private static final int MIN_DEBUGGER_IDLE = 1300; // msec
94
95 /* how long to sleep when polling for activity */
96 private static final int SPIN_DELAY = 200; // msec
97
98 /**
99 * Default trace file path and file
100 */
Christian Mehlmauer798e2d32010-06-17 18:24:07 +0200101 private static final String DEFAULT_TRACE_PATH_PREFIX =
Jeff Sharkeyb049e212012-09-07 23:16:01 -0700102 Environment.getLegacyExternalStorageDirectory().getPath() + "/";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 private static final String DEFAULT_TRACE_BODY = "dmtrace";
104 private static final String DEFAULT_TRACE_EXTENSION = ".trace";
105 private static final String DEFAULT_TRACE_FILE_PATH =
106 DEFAULT_TRACE_PATH_PREFIX + DEFAULT_TRACE_BODY
107 + DEFAULT_TRACE_EXTENSION;
108
109
110 /**
111 * This class is used to retrieved various statistics about the memory mappings for this
justinmuller64551382013-10-16 22:06:55 -0600112 * process. The returned info is broken down by dalvik, native, and other. All results are in kB.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113 */
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700114 public static class MemoryInfo implements Parcelable {
Dianne Hackborn64770d12013-05-23 17:51:19 -0700115 /** The proportional set size for dalvik heap. (Doesn't include other Dalvik overhead.) */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 public int dalvikPss;
Dianne Hackborn64770d12013-05-23 17:51:19 -0700117 /** The proportional set size that is swappable for dalvik heap. */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700118 /** @hide We may want to expose this, eventually. */
119 public int dalvikSwappablePss;
Dianne Hackborn64770d12013-05-23 17:51:19 -0700120 /** The private dirty pages used by dalvik heap. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121 public int dalvikPrivateDirty;
Dianne Hackborn64770d12013-05-23 17:51:19 -0700122 /** The shared dirty pages used by dalvik heap. */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123 public int dalvikSharedDirty;
Dianne Hackborn64770d12013-05-23 17:51:19 -0700124 /** The private clean pages used by dalvik heap. */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700125 /** @hide We may want to expose this, eventually. */
126 public int dalvikPrivateClean;
Dianne Hackborn64770d12013-05-23 17:51:19 -0700127 /** The shared clean pages used by dalvik heap. */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700128 /** @hide We may want to expose this, eventually. */
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700129 public int dalvikSharedClean;
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700130 /** The dirty dalvik pages that have been swapped out. */
131 /** @hide We may want to expose this, eventually. */
132 public int dalvikSwappedOut;
Martijn Coenene0764852016-01-07 17:04:22 -0800133 /** The dirty dalvik pages that have been swapped out, proportional. */
134 /** @hide We may want to expose this, eventually. */
135 public int dalvikSwappedOutPss;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136
137 /** The proportional set size for the native heap. */
138 public int nativePss;
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700139 /** The proportional set size that is swappable for the native heap. */
140 /** @hide We may want to expose this, eventually. */
141 public int nativeSwappablePss;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 /** The private dirty pages used by the native heap. */
143 public int nativePrivateDirty;
144 /** The shared dirty pages used by the native heap. */
145 public int nativeSharedDirty;
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700146 /** The private clean pages used by the native heap. */
147 /** @hide We may want to expose this, eventually. */
148 public int nativePrivateClean;
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700149 /** The shared clean pages used by the native heap. */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700150 /** @hide We may want to expose this, eventually. */
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700151 public int nativeSharedClean;
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700152 /** The dirty native pages that have been swapped out. */
153 /** @hide We may want to expose this, eventually. */
154 public int nativeSwappedOut;
Martijn Coenene0764852016-01-07 17:04:22 -0800155 /** The dirty native pages that have been swapped out, proportional. */
156 /** @hide We may want to expose this, eventually. */
157 public int nativeSwappedOutPss;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158
159 /** The proportional set size for everything else. */
160 public int otherPss;
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700161 /** The proportional set size that is swappable for everything else. */
162 /** @hide We may want to expose this, eventually. */
163 public int otherSwappablePss;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 /** The private dirty pages used by everything else. */
165 public int otherPrivateDirty;
166 /** The shared dirty pages used by everything else. */
167 public int otherSharedDirty;
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700168 /** The private clean pages used by everything else. */
169 /** @hide We may want to expose this, eventually. */
170 public int otherPrivateClean;
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700171 /** The shared clean pages used by everything else. */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700172 /** @hide We may want to expose this, eventually. */
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700173 public int otherSharedClean;
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700174 /** The dirty pages used by anyting else that have been swapped out. */
175 /** @hide We may want to expose this, eventually. */
176 public int otherSwappedOut;
Martijn Coenene0764852016-01-07 17:04:22 -0800177 /** The dirty pages used by anyting else that have been swapped out, proportional. */
178 /** @hide We may want to expose this, eventually. */
179 public int otherSwappedOutPss;
180
181 /** Whether the kernel reports proportional swap usage */
182 /** @hide */
183 public boolean hasSwappedOutPss;
Christian Mehlmauer798e2d32010-06-17 18:24:07 +0200184
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700185 /** @hide */
Richard Uhlerc14b9cf2015-03-13 12:38:38 -0700186 public static final int HEAP_UNKNOWN = 0;
187 /** @hide */
188 public static final int HEAP_DALVIK = 1;
189 /** @hide */
190 public static final int HEAP_NATIVE = 2;
191
192 /** @hide */
193 public static final int OTHER_DALVIK_OTHER = 0;
194 /** @hide */
195 public static final int OTHER_STACK = 1;
196 /** @hide */
197 public static final int OTHER_CURSOR = 2;
198 /** @hide */
199 public static final int OTHER_ASHMEM = 3;
200 /** @hide */
201 public static final int OTHER_GL_DEV = 4;
202 /** @hide */
203 public static final int OTHER_UNKNOWN_DEV = 5;
204 /** @hide */
205 public static final int OTHER_SO = 6;
206 /** @hide */
207 public static final int OTHER_JAR = 7;
208 /** @hide */
209 public static final int OTHER_APK = 8;
210 /** @hide */
211 public static final int OTHER_TTF = 9;
212 /** @hide */
213 public static final int OTHER_DEX = 10;
214 /** @hide */
215 public static final int OTHER_OAT = 11;
216 /** @hide */
217 public static final int OTHER_ART = 12;
218 /** @hide */
219 public static final int OTHER_UNKNOWN_MAP = 13;
220 /** @hide */
221 public static final int OTHER_GRAPHICS = 14;
222 /** @hide */
223 public static final int OTHER_GL = 15;
224 /** @hide */
225 public static final int OTHER_OTHER_MEMTRACK = 16;
226
227 /** @hide */
228 public static final int OTHER_DALVIK_NORMAL = 17;
229 /** @hide */
230 public static final int OTHER_DALVIK_LARGE = 18;
231 /** @hide */
232 public static final int OTHER_DALVIK_LINEARALLOC = 19;
233 /** @hide */
234 public static final int OTHER_DALVIK_ACCOUNTING = 20;
235 /** @hide */
236 public static final int OTHER_DALVIK_CODE_CACHE = 21;
237 /** @hide */
238 public static final int OTHER_DALVIK_ZYGOTE = 22;
239 /** @hide */
240 public static final int OTHER_DALVIK_NON_MOVING = 23;
241 /** @hide */
242 public static final int OTHER_DALVIK_INDIRECT_REFERENCE_TABLE = 24;
243
244 /** @hide */
Dianne Hackborn18429302014-11-03 13:58:11 -0800245 public static final int NUM_OTHER_STATS = 17;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700246
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700247 /** @hide */
Mathieu Chartier25c5e2b2014-12-08 16:20:26 -0800248 public static final int NUM_DVK_STATS = 8;
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700249
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700250 /** @hide */
Martijn Coenene0764852016-01-07 17:04:22 -0800251 public static final int NUM_CATEGORIES = 8;
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700252
253 /** @hide */
254 public static final int offsetPss = 0;
255 /** @hide */
256 public static final int offsetSwappablePss = 1;
257 /** @hide */
258 public static final int offsetPrivateDirty = 2;
259 /** @hide */
260 public static final int offsetSharedDirty = 3;
261 /** @hide */
262 public static final int offsetPrivateClean = 4;
263 /** @hide */
264 public static final int offsetSharedClean = 5;
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700265 /** @hide */
266 public static final int offsetSwappedOut = 6;
Martijn Coenene0764852016-01-07 17:04:22 -0800267 /** @hide */
268 public static final int offsetSwappedOutPss = 7;
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700269
270 private int[] otherStats = new int[(NUM_OTHER_STATS+NUM_DVK_STATS)*NUM_CATEGORIES];
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700271
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700272 public MemoryInfo() {
273 }
274
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -0700275 /**
276 * Return total PSS memory usage in kB.
277 */
278 public int getTotalPss() {
Martijn Coenene0764852016-01-07 17:04:22 -0800279 return dalvikPss + nativePss + otherPss + getTotalSwappedOutPss();
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -0700280 }
Christian Mehlmauer798e2d32010-06-17 18:24:07 +0200281
Dianne Hackbornc8230512013-07-13 21:32:12 -0700282 /**
283 * @hide Return total PSS memory usage in kB.
284 */
285 public int getTotalUss() {
286 return dalvikPrivateClean + dalvikPrivateDirty
287 + nativePrivateClean + nativePrivateDirty
288 + otherPrivateClean + otherPrivateDirty;
289 }
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700290
291 /**
Martijn Coenene0764852016-01-07 17:04:22 -0800292 * Return total PSS memory usage in kB mapping a file of one of the following extension:
293 * .so, .jar, .apk, .ttf, .dex, .odex, .oat, .art .
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700294 */
295 public int getTotalSwappablePss() {
296 return dalvikSwappablePss + nativeSwappablePss + otherSwappablePss;
297 }
298
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -0700299 /**
300 * Return total private dirty memory usage in kB.
301 */
302 public int getTotalPrivateDirty() {
303 return dalvikPrivateDirty + nativePrivateDirty + otherPrivateDirty;
304 }
Christian Mehlmauer798e2d32010-06-17 18:24:07 +0200305
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -0700306 /**
307 * Return total shared dirty memory usage in kB.
308 */
309 public int getTotalSharedDirty() {
310 return dalvikSharedDirty + nativeSharedDirty + otherSharedDirty;
311 }
Christian Mehlmauer798e2d32010-06-17 18:24:07 +0200312
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700313 /**
314 * Return total shared clean memory usage in kB.
315 */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700316 public int getTotalPrivateClean() {
317 return dalvikPrivateClean + nativePrivateClean + otherPrivateClean;
318 }
319
320 /**
321 * Return total shared clean memory usage in kB.
322 */
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700323 public int getTotalSharedClean() {
324 return dalvikSharedClean + nativeSharedClean + otherSharedClean;
325 }
326
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700327 /**
328 * Return total swapped out memory in kB.
329 * @hide
330 */
331 public int getTotalSwappedOut() {
332 return dalvikSwappedOut + nativeSwappedOut + otherSwappedOut;
333 }
334
Martijn Coenene0764852016-01-07 17:04:22 -0800335 /**
336 * Return total swapped out memory in kB, proportional.
337 * @hide
338 */
339 public int getTotalSwappedOutPss() {
340 return dalvikSwappedOutPss + nativeSwappedOutPss + otherSwappedOutPss;
341 }
342
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700343 /** @hide */
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700344 public int getOtherPss(int which) {
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700345 return otherStats[which*NUM_CATEGORIES + offsetPss];
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700346 }
347
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700348
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700349 /** @hide */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700350 public int getOtherSwappablePss(int which) {
351 return otherStats[which*NUM_CATEGORIES + offsetSwappablePss];
352 }
353
354
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700355 /** @hide */
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700356 public int getOtherPrivateDirty(int which) {
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700357 return otherStats[which*NUM_CATEGORIES + offsetPrivateDirty];
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700358 }
359
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700360 /** @hide */
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700361 public int getOtherSharedDirty(int which) {
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700362 return otherStats[which*NUM_CATEGORIES + offsetSharedDirty];
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700363 }
364
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700365 /** @hide */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700366 public int getOtherPrivateClean(int which) {
367 return otherStats[which*NUM_CATEGORIES + offsetPrivateClean];
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700368 }
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700369
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700370 /** @hide */
Richard Uhlerc14b9cf2015-03-13 12:38:38 -0700371 public int getOtherPrivate(int which) {
372 return getOtherPrivateClean(which) + getOtherPrivateDirty(which);
373 }
374
375 /** @hide */
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700376 public int getOtherSharedClean(int which) {
377 return otherStats[which*NUM_CATEGORIES + offsetSharedClean];
378 }
379
Dianne Hackborn3fa89692013-09-13 17:20:00 -0700380 /** @hide */
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700381 public int getOtherSwappedOut(int which) {
382 return otherStats[which*NUM_CATEGORIES + offsetSwappedOut];
383 }
384
385 /** @hide */
Martijn Coenene0764852016-01-07 17:04:22 -0800386 public int getOtherSwappedOutPss(int which) {
387 return otherStats[which*NUM_CATEGORIES + offsetSwappedOutPss];
388 }
389
390 /** @hide */
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700391 public static String getOtherLabel(int which) {
392 switch (which) {
Richard Uhlerc14b9cf2015-03-13 12:38:38 -0700393 case OTHER_DALVIK_OTHER: return "Dalvik Other";
394 case OTHER_STACK: return "Stack";
395 case OTHER_CURSOR: return "Cursor";
396 case OTHER_ASHMEM: return "Ashmem";
397 case OTHER_GL_DEV: return "Gfx dev";
398 case OTHER_UNKNOWN_DEV: return "Other dev";
399 case OTHER_SO: return ".so mmap";
400 case OTHER_JAR: return ".jar mmap";
401 case OTHER_APK: return ".apk mmap";
402 case OTHER_TTF: return ".ttf mmap";
403 case OTHER_DEX: return ".dex mmap";
404 case OTHER_OAT: return ".oat mmap";
405 case OTHER_ART: return ".art mmap";
406 case OTHER_UNKNOWN_MAP: return "Other mmap";
407 case OTHER_GRAPHICS: return "EGL mtrack";
408 case OTHER_GL: return "GL mtrack";
409 case OTHER_OTHER_MEMTRACK: return "Other mtrack";
410 case OTHER_DALVIK_NORMAL: return ".Heap";
411 case OTHER_DALVIK_LARGE: return ".LOS";
412 case OTHER_DALVIK_LINEARALLOC: return ".LinearAlloc";
413 case OTHER_DALVIK_ACCOUNTING: return ".GC";
414 case OTHER_DALVIK_CODE_CACHE: return ".JITCache";
415 case OTHER_DALVIK_ZYGOTE: return ".Zygote";
416 case OTHER_DALVIK_NON_MOVING: return ".NonMoving";
417 case OTHER_DALVIK_INDIRECT_REFERENCE_TABLE: return ".IndirectRef";
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700418 default: return "????";
419 }
420 }
421
Richard Uhler350e6dc2015-05-18 10:48:52 -0700422 /**
423 * Returns the value of a particular memory statistic or {@code null} if no
424 * such memory statistic exists.
425 *
426 * <p>The following table lists the memory statistics that are supported.
427 * Note that memory statistics may be added or removed in a future API level.</p>
428 *
429 * <table>
430 * <thead>
431 * <tr>
432 * <th>Memory statistic name</th>
433 * <th>Meaning</th>
434 * <th>Example</th>
435 * <th>Supported (API Levels)</th>
436 * </tr>
437 * </thead>
438 * <tbody>
439 * <tr>
440 * <td>summary.java-heap</td>
441 * <td>The private Java Heap usage in kB. This corresponds to the Java Heap field
442 * in the App Summary section output by dumpsys meminfo.</td>
443 * <td>{@code 1442}</td>
444 * <td>23</td>
445 * </tr>
446 * <tr>
447 * <td>summary.native-heap</td>
448 * <td>The private Native Heap usage in kB. This corresponds to the Native Heap
449 * field in the App Summary section output by dumpsys meminfo.</td>
450 * <td>{@code 1442}</td>
451 * <td>23</td>
452 * </tr>
453 * <tr>
454 * <td>summary.code</td>
455 * <td>The memory usage for static code and resources in kB. This corresponds to
456 * the Code field in the App Summary section output by dumpsys meminfo.</td>
457 * <td>{@code 1442}</td>
458 * <td>23</td>
459 * </tr>
460 * <tr>
461 * <td>summary.stack</td>
462 * <td>The stack usage in kB. This corresponds to the Stack field in the
463 * App Summary section output by dumpsys meminfo.</td>
464 * <td>{@code 1442}</td>
465 * <td>23</td>
466 * </tr>
467 * <tr>
468 * <td>summary.graphics</td>
469 * <td>The graphics usage in kB. This corresponds to the Graphics field in the
470 * App Summary section output by dumpsys meminfo.</td>
471 * <td>{@code 1442}</td>
472 * <td>23</td>
473 * </tr>
474 * <tr>
475 * <td>summary.private-other</td>
476 * <td>Other private memory usage in kB. This corresponds to the Private Other
477 * field output in the App Summary section by dumpsys meminfo.</td>
478 * <td>{@code 1442}</td>
479 * <td>23</td>
480 * </tr>
481 * <tr>
482 * <td>summary.system</td>
483 * <td>Shared and system memory usage in kB. This corresponds to the System
484 * field output in the App Summary section by dumpsys meminfo.</td>
485 * <td>{@code 1442}</td>
486 * <td>23</td>
487 * </tr>
488 * <tr>
489 * <td>summary.total-pss</td>
490 * <td>Total PPS memory usage in kB.</td>
491 * <td>{@code 1442}</td>
492 * <td>23</td>
493 * </tr>
494 * <tr>
495 * <td>summary.total-swap</td>
496 * <td>Total swap usage in kB.</td>
497 * <td>{@code 1442}</td>
498 * <td>23</td>
499 * </tr>
500 * </tbody>
501 * </table>
502 */
Dianne Hackbornb02ce292015-10-12 15:14:16 -0700503 public String getMemoryStat(String statName) {
Richard Uhler350e6dc2015-05-18 10:48:52 -0700504 switch(statName) {
505 case "summary.java-heap":
506 return Integer.toString(getSummaryJavaHeap());
507 case "summary.native-heap":
508 return Integer.toString(getSummaryNativeHeap());
509 case "summary.code":
510 return Integer.toString(getSummaryCode());
511 case "summary.stack":
512 return Integer.toString(getSummaryStack());
513 case "summary.graphics":
514 return Integer.toString(getSummaryGraphics());
515 case "summary.private-other":
516 return Integer.toString(getSummaryPrivateOther());
517 case "summary.system":
518 return Integer.toString(getSummarySystem());
519 case "summary.total-pss":
520 return Integer.toString(getSummaryTotalPss());
521 case "summary.total-swap":
522 return Integer.toString(getSummaryTotalSwap());
523 default:
524 return null;
525 }
526 }
527
528 /**
529 * Returns a map of the names/values of the memory statistics
530 * that {@link #getMemoryStat(String)} supports.
531 *
532 * @return a map of the names/values of the supported memory statistics.
533 */
534 public Map<String, String> getMemoryStats() {
535 Map<String, String> stats = new HashMap<String, String>();
536 stats.put("summary.java-heap", Integer.toString(getSummaryJavaHeap()));
537 stats.put("summary.native-heap", Integer.toString(getSummaryNativeHeap()));
538 stats.put("summary.code", Integer.toString(getSummaryCode()));
539 stats.put("summary.stack", Integer.toString(getSummaryStack()));
540 stats.put("summary.graphics", Integer.toString(getSummaryGraphics()));
541 stats.put("summary.private-other", Integer.toString(getSummaryPrivateOther()));
542 stats.put("summary.system", Integer.toString(getSummarySystem()));
543 stats.put("summary.total-pss", Integer.toString(getSummaryTotalPss()));
544 stats.put("summary.total-swap", Integer.toString(getSummaryTotalSwap()));
545 return stats;
546 }
547
Richard Uhlerc14b9cf2015-03-13 12:38:38 -0700548 /**
549 * Pss of Java Heap bytes in KB due to the application.
550 * Notes:
551 * * OTHER_ART is the boot image. Anything private here is blamed on
552 * the application, not the system.
553 * * dalvikPrivateDirty includes private zygote, which means the
554 * application dirtied something allocated by the zygote. We blame
555 * the application for that memory, not the system.
556 * * Does not include OTHER_DALVIK_OTHER, which is considered VM
557 * Overhead and lumped into Private Other.
558 * * We don't include dalvikPrivateClean, because there should be no
559 * such thing as private clean for the Java Heap.
560 * @hide
561 */
562 public int getSummaryJavaHeap() {
563 return dalvikPrivateDirty + getOtherPrivate(OTHER_ART);
564 }
565
566 /**
567 * Pss of Native Heap bytes in KB due to the application.
568 * Notes:
569 * * Includes private dirty malloc space.
570 * * We don't include nativePrivateClean, because there should be no
571 * such thing as private clean for the Native Heap.
572 * @hide
573 */
574 public int getSummaryNativeHeap() {
575 return nativePrivateDirty;
576 }
577
578 /**
579 * Pss of code and other static resource bytes in KB due to
580 * the application.
581 * @hide
582 */
583 public int getSummaryCode() {
584 return getOtherPrivate(OTHER_SO)
585 + getOtherPrivate(OTHER_JAR)
586 + getOtherPrivate(OTHER_APK)
587 + getOtherPrivate(OTHER_TTF)
588 + getOtherPrivate(OTHER_DEX)
589 + getOtherPrivate(OTHER_OAT);
590 }
591
592 /**
593 * Pss in KB of the stack due to the application.
594 * Notes:
595 * * Includes private dirty stack, which includes both Java and Native
596 * stack.
597 * * Does not include private clean stack, because there should be no
598 * such thing as private clean for the stack.
599 * @hide
600 */
601 public int getSummaryStack() {
602 return getOtherPrivateDirty(OTHER_STACK);
603 }
604
605 /**
606 * Pss in KB of graphics due to the application.
607 * Notes:
608 * * Includes private Gfx, EGL, and GL.
609 * * Warning: These numbers can be misreported by the graphics drivers.
610 * * We don't include shared graphics. It may make sense to, because
611 * shared graphics are likely buffers due to the application
612 * anyway, but it's simpler to implement to just group all shared
613 * memory into the System category.
614 * @hide
615 */
616 public int getSummaryGraphics() {
617 return getOtherPrivate(OTHER_GL_DEV)
618 + getOtherPrivate(OTHER_GRAPHICS)
619 + getOtherPrivate(OTHER_GL);
620 }
621
622 /**
623 * Pss in KB due to the application that haven't otherwise been
624 * accounted for.
625 * @hide
626 */
627 public int getSummaryPrivateOther() {
628 return getTotalPrivateClean()
629 + getTotalPrivateDirty()
630 - getSummaryJavaHeap()
631 - getSummaryNativeHeap()
632 - getSummaryCode()
633 - getSummaryStack()
634 - getSummaryGraphics();
635 }
636
637 /**
638 * Pss in KB due to the system.
639 * Notes:
640 * * Includes all shared memory.
641 * @hide
642 */
643 public int getSummarySystem() {
644 return getTotalPss()
645 - getTotalPrivateClean()
646 - getTotalPrivateDirty();
647 }
648
649 /**
650 * Total Pss in KB.
651 * @hide
652 */
653 public int getSummaryTotalPss() {
654 return getTotalPss();
655 }
656
657 /**
658 * Total Swap in KB.
659 * Notes:
660 * * Some of this memory belongs in other categories, but we don't
661 * know if the Swap memory is shared or private, so we don't know
662 * what to blame on the application and what on the system.
663 * For now, just lump all the Swap in one place.
Martijn Coenene0764852016-01-07 17:04:22 -0800664 * For kernels reporting SwapPss {@link #getSummaryTotalSwapPss()}
665 * will report the application proportional Swap.
Richard Uhlerc14b9cf2015-03-13 12:38:38 -0700666 * @hide
667 */
668 public int getSummaryTotalSwap() {
669 return getTotalSwappedOut();
670 }
671
Martijn Coenene0764852016-01-07 17:04:22 -0800672 /**
673 * Total proportional Swap in KB.
674 * Notes:
675 * * Always 0 if {@link #hasSwappedOutPss} is false.
676 * @hide
677 */
678 public int getSummaryTotalSwapPss() {
679 return getTotalSwappedOutPss();
680 }
681
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700682 public int describeContents() {
683 return 0;
684 }
685
686 public void writeToParcel(Parcel dest, int flags) {
687 dest.writeInt(dalvikPss);
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700688 dest.writeInt(dalvikSwappablePss);
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700689 dest.writeInt(dalvikPrivateDirty);
690 dest.writeInt(dalvikSharedDirty);
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700691 dest.writeInt(dalvikPrivateClean);
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700692 dest.writeInt(dalvikSharedClean);
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700693 dest.writeInt(dalvikSwappedOut);
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700694 dest.writeInt(nativePss);
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700695 dest.writeInt(nativeSwappablePss);
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700696 dest.writeInt(nativePrivateDirty);
697 dest.writeInt(nativeSharedDirty);
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700698 dest.writeInt(nativePrivateClean);
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700699 dest.writeInt(nativeSharedClean);
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700700 dest.writeInt(nativeSwappedOut);
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700701 dest.writeInt(otherPss);
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700702 dest.writeInt(otherSwappablePss);
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700703 dest.writeInt(otherPrivateDirty);
704 dest.writeInt(otherSharedDirty);
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700705 dest.writeInt(otherPrivateClean);
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700706 dest.writeInt(otherSharedClean);
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700707 dest.writeInt(otherSwappedOut);
Martijn Coenene0764852016-01-07 17:04:22 -0800708 dest.writeInt(hasSwappedOutPss ? 1 : 0);
709 dest.writeInt(otherSwappedOutPss);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700710 dest.writeIntArray(otherStats);
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700711 }
712
713 public void readFromParcel(Parcel source) {
714 dalvikPss = source.readInt();
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700715 dalvikSwappablePss = source.readInt();
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700716 dalvikPrivateDirty = source.readInt();
717 dalvikSharedDirty = source.readInt();
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700718 dalvikPrivateClean = source.readInt();
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700719 dalvikSharedClean = source.readInt();
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700720 dalvikSwappedOut = source.readInt();
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700721 nativePss = source.readInt();
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700722 nativeSwappablePss = source.readInt();
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700723 nativePrivateDirty = source.readInt();
724 nativeSharedDirty = source.readInt();
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700725 nativePrivateClean = source.readInt();
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700726 nativeSharedClean = source.readInt();
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700727 nativeSwappedOut = source.readInt();
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700728 otherPss = source.readInt();
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700729 otherSwappablePss = source.readInt();
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700730 otherPrivateDirty = source.readInt();
731 otherSharedDirty = source.readInt();
Anwar Ghuloum3c615062013-05-13 14:18:02 -0700732 otherPrivateClean = source.readInt();
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -0700733 otherSharedClean = source.readInt();
Dianne Hackborn8883ced2013-10-02 16:58:06 -0700734 otherSwappedOut = source.readInt();
Martijn Coenene0764852016-01-07 17:04:22 -0800735 hasSwappedOutPss = source.readInt() != 0;
736 otherSwappedOutPss = source.readInt();
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700737 otherStats = source.createIntArray();
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700738 }
Christian Mehlmauer798e2d32010-06-17 18:24:07 +0200739
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700740 public static final Creator<MemoryInfo> CREATOR = new Creator<MemoryInfo>() {
741 public MemoryInfo createFromParcel(Parcel source) {
742 return new MemoryInfo(source);
743 }
744 public MemoryInfo[] newArray(int size) {
745 return new MemoryInfo[size];
746 }
747 };
748
749 private MemoryInfo(Parcel source) {
750 readFromParcel(source);
751 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800752 }
753
754
755 /**
756 * Wait until a debugger attaches. As soon as the debugger attaches,
757 * this returns, so you will need to place a breakpoint after the
758 * waitForDebugger() call if you want to start tracing immediately.
759 */
760 public static void waitForDebugger() {
761 if (!VMDebug.isDebuggingEnabled()) {
762 //System.out.println("debugging not enabled, not waiting");
763 return;
764 }
765 if (isDebuggerConnected())
766 return;
767
768 // if DDMS is listening, inform them of our plight
769 System.out.println("Sending WAIT chunk");
770 byte[] data = new byte[] { 0 }; // 0 == "waiting for debugger"
771 Chunk waitChunk = new Chunk(ChunkHandler.type("WAIT"), data, 0, 1);
772 DdmServer.sendChunk(waitChunk);
773
774 mWaiting = true;
775 while (!isDebuggerConnected()) {
776 try { Thread.sleep(SPIN_DELAY); }
777 catch (InterruptedException ie) {}
778 }
779 mWaiting = false;
780
781 System.out.println("Debugger has connected");
782
783 /*
784 * There is no "ready to go" signal from the debugger, and we're
785 * not allowed to suspend ourselves -- the debugger expects us to
786 * be running happily, and gets confused if we aren't. We need to
787 * allow the debugger a chance to set breakpoints before we start
788 * running again.
789 *
790 * Sit and spin until the debugger has been idle for a short while.
791 */
792 while (true) {
793 long delta = VMDebug.lastDebuggerActivity();
794 if (delta < 0) {
795 System.out.println("debugger detached?");
796 break;
797 }
798
799 if (delta < MIN_DEBUGGER_IDLE) {
800 System.out.println("waiting for debugger to settle...");
801 try { Thread.sleep(SPIN_DELAY); }
802 catch (InterruptedException ie) {}
803 } else {
804 System.out.println("debugger has settled (" + delta + ")");
805 break;
806 }
807 }
808 }
809
810 /**
811 * Returns "true" if one or more threads is waiting for a debugger
812 * to attach.
813 */
814 public static boolean waitingForDebugger() {
815 return mWaiting;
816 }
817
818 /**
819 * Determine if a debugger is currently attached.
820 */
821 public static boolean isDebuggerConnected() {
822 return VMDebug.isDebuggerConnected();
823 }
824
825 /**
Andy McFaddene5772322010-01-22 07:23:31 -0800826 * Returns an array of strings that identify VM features. This is
827 * used by DDMS to determine what sorts of operations the VM can
828 * perform.
829 *
830 * @hide
831 */
832 public static String[] getVmFeatureList() {
833 return VMDebug.getVmFeatureList();
834 }
835
836 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800837 * Change the JDWP port.
838 *
839 * @deprecated no longer needed or useful
840 */
841 @Deprecated
842 public static void changeDebugPort(int port) {}
843
844 /**
845 * This is the pathname to the sysfs file that enables and disables
846 * tracing on the qemu emulator.
847 */
848 private static final String SYSFS_QEMU_TRACE_STATE = "/sys/qemu_trace/state";
849
850 /**
851 * Enable qemu tracing. For this to work requires running everything inside
852 * the qemu emulator; otherwise, this method will have no effect. The trace
853 * file is specified on the command line when the emulator is started. For
854 * example, the following command line <br />
855 * <code>emulator -trace foo</code><br />
856 * will start running the emulator and create a trace file named "foo". This
857 * method simply enables writing the trace records to the trace file.
858 *
859 * <p>
860 * The main differences between this and {@link #startMethodTracing()} are
861 * that tracing in the qemu emulator traces every cpu instruction of every
862 * process, including kernel code, so we have more complete information,
863 * including all context switches. We can also get more detailed information
864 * such as cache misses. The sequence of calls is determined by
865 * post-processing the instruction trace. The qemu tracing is also done
866 * without modifying the application or perturbing the timing of calls
867 * because no instrumentation is added to the application being traced.
868 * </p>
869 *
870 * <p>
871 * One limitation of using this method compared to using
872 * {@link #startMethodTracing()} on the real device is that the emulator
873 * does not model all of the real hardware effects such as memory and
874 * bus contention. The emulator also has a simple cache model and cannot
875 * capture all the complexities of a real cache.
876 * </p>
877 */
878 public static void startNativeTracing() {
879 // Open the sysfs file for writing and write "1" to it.
880 PrintWriter outStream = null;
881 try {
882 FileOutputStream fos = new FileOutputStream(SYSFS_QEMU_TRACE_STATE);
Dianne Hackborn8c841092013-06-24 13:46:13 -0700883 outStream = new FastPrintWriter(fos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800884 outStream.println("1");
885 } catch (Exception e) {
886 } finally {
887 if (outStream != null)
888 outStream.close();
889 }
890
891 VMDebug.startEmulatorTracing();
892 }
893
894 /**
895 * Stop qemu tracing. See {@link #startNativeTracing()} to start tracing.
896 *
897 * <p>Tracing can be started and stopped as many times as desired. When
898 * the qemu emulator itself is stopped then the buffered trace records
899 * are flushed and written to the trace file. In fact, it is not necessary
900 * to call this method at all; simply killing qemu is sufficient. But
901 * starting and stopping a trace is useful for examining a specific
902 * region of code.</p>
903 */
904 public static void stopNativeTracing() {
905 VMDebug.stopEmulatorTracing();
906
907 // Open the sysfs file for writing and write "0" to it.
908 PrintWriter outStream = null;
909 try {
910 FileOutputStream fos = new FileOutputStream(SYSFS_QEMU_TRACE_STATE);
Dianne Hackborn8c841092013-06-24 13:46:13 -0700911 outStream = new FastPrintWriter(fos);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800912 outStream.println("0");
913 } catch (Exception e) {
914 // We could print an error message here but we probably want
915 // to quietly ignore errors if we are not running in the emulator.
916 } finally {
917 if (outStream != null)
918 outStream.close();
919 }
920 }
921
922 /**
923 * Enable "emulator traces", in which information about the current
924 * method is made available to the "emulator -trace" feature. There
925 * is no corresponding "disable" call -- this is intended for use by
926 * the framework when tracing should be turned on and left that way, so
927 * that traces captured with F9/F10 will include the necessary data.
928 *
929 * This puts the VM into "profile" mode, which has performance
930 * consequences.
931 *
932 * To temporarily enable tracing, use {@link #startNativeTracing()}.
933 */
934 public static void enableEmulatorTraceOutput() {
935 VMDebug.startEmulatorTracing();
936 }
937
938 /**
939 * Start method tracing with default log name and buffer size. See <a
940href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
941 * information about reading these files. Call stopMethodTracing() to stop
942 * tracing.
943 */
944 public static void startMethodTracing() {
Jeff Haod02e60f2014-01-06 15:52:52 -0800945 VMDebug.startMethodTracing(DEFAULT_TRACE_FILE_PATH, 0, 0, false, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800946 }
947
948 /**
949 * Start method tracing, specifying the trace log file name. The trace
950 * file will be put under "/sdcard" unless an absolute path is given.
951 * See <a
952 href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
953 * information about reading trace files.
954 *
955 * @param traceName Name for the trace log file to create.
Jeff Haod02e60f2014-01-06 15:52:52 -0800956 * If {@code traceName} is null, this value defaults to "/sdcard/dmtrace.trace".
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800957 * If the files already exist, they will be truncated.
958 * If the trace file given does not end in ".trace", it will be appended for you.
959 */
960 public static void startMethodTracing(String traceName) {
961 startMethodTracing(traceName, 0, 0);
962 }
963
964 /**
965 * Start method tracing, specifying the trace log file name and the
966 * buffer size. The trace files will be put under "/sdcard" unless an
967 * absolute path is given. See <a
968 href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
969 * information about reading trace files.
970 * @param traceName Name for the trace log file to create.
Jeff Haod02e60f2014-01-06 15:52:52 -0800971 * If {@code traceName} is null, this value defaults to "/sdcard/dmtrace.trace".
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800972 * If the files already exist, they will be truncated.
973 * If the trace file given does not end in ".trace", it will be appended for you.
974 *
975 * @param bufferSize The maximum amount of trace data we gather. If not given, it defaults to 8MB.
976 */
977 public static void startMethodTracing(String traceName, int bufferSize) {
978 startMethodTracing(traceName, bufferSize, 0);
979 }
980
981 /**
982 * Start method tracing, specifying the trace log file name and the
983 * buffer size. The trace files will be put under "/sdcard" unless an
984 * absolute path is given. See <a
985 href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a> for
986 * information about reading trace files.
987 *
988 * <p>
989 * When method tracing is enabled, the VM will run more slowly than
990 * usual, so the timings from the trace files should only be considered
991 * in relative terms (e.g. was run #1 faster than run #2). The times
992 * for native methods will not change, so don't try to use this to
993 * compare the performance of interpreted and native implementations of the
Jeff Haod02e60f2014-01-06 15:52:52 -0800994 * same method. As an alternative, consider using sampling-based method
995 * tracing via {@link #startMethodTracingSampling(String, int, int)} or
996 * "native" tracing in the emulator via {@link #startNativeTracing()}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800997 * </p>
998 *
999 * @param traceName Name for the trace log file to create.
Jeff Haod02e60f2014-01-06 15:52:52 -08001000 * If {@code traceName} is null, this value defaults to "/sdcard/dmtrace.trace".
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001001 * If the files already exist, they will be truncated.
1002 * If the trace file given does not end in ".trace", it will be appended for you.
1003 * @param bufferSize The maximum amount of trace data we gather. If not given, it defaults to 8MB.
Jeff Haod02e60f2014-01-06 15:52:52 -08001004 * @param flags Flags to control method tracing. The only one that is currently defined is {@link #TRACE_COUNT_ALLOCS}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001005 */
1006 public static void startMethodTracing(String traceName, int bufferSize,
1007 int flags) {
Jeff Haod02e60f2014-01-06 15:52:52 -08001008 VMDebug.startMethodTracing(fixTraceName(traceName), bufferSize, flags, false, 0);
1009 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001010
Jeff Haod02e60f2014-01-06 15:52:52 -08001011 /**
1012 * Start sampling-based method tracing, specifying the trace log file name,
1013 * the buffer size, and the sampling interval. The trace files will be put
1014 * under "/sdcard" unless an absolute path is given. See <a
1015 href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Log Viewer</a>
1016 * for information about reading trace files.
1017 *
1018 * @param traceName Name for the trace log file to create.
1019 * If {@code traceName} is null, this value defaults to "/sdcard/dmtrace.trace".
1020 * If the files already exist, they will be truncated.
1021 * If the trace file given does not end in ".trace", it will be appended for you.
1022 * @param bufferSize The maximum amount of trace data we gather. If not given, it defaults to 8MB.
1023 * @param intervalUs The amount of time between each sample in microseconds.
1024 */
1025 public static void startMethodTracingSampling(String traceName,
1026 int bufferSize, int intervalUs) {
1027 VMDebug.startMethodTracing(fixTraceName(traceName), bufferSize, 0, true, intervalUs);
1028 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001029
Jeff Haod02e60f2014-01-06 15:52:52 -08001030 /**
1031 * Formats name of trace log file for method tracing.
1032 */
1033 private static String fixTraceName(String traceName) {
1034 if (traceName == null)
1035 traceName = DEFAULT_TRACE_FILE_PATH;
1036 if (traceName.charAt(0) != '/')
1037 traceName = DEFAULT_TRACE_PATH_PREFIX + traceName;
1038 if (!traceName.endsWith(DEFAULT_TRACE_EXTENSION))
1039 traceName = traceName + DEFAULT_TRACE_EXTENSION;
1040
1041 return traceName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001042 }
1043
1044 /**
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07001045 * Like startMethodTracing(String, int, int), but taking an already-opened
1046 * FileDescriptor in which the trace is written. The file name is also
1047 * supplied simply for logging. Makes a dup of the file descriptor.
Christian Mehlmauer798e2d32010-06-17 18:24:07 +02001048 *
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07001049 * Not exposed in the SDK unless we are really comfortable with supporting
1050 * this and find it would be useful.
1051 * @hide
1052 */
1053 public static void startMethodTracing(String traceName, FileDescriptor fd,
1054 int bufferSize, int flags) {
Jeff Haod02e60f2014-01-06 15:52:52 -08001055 VMDebug.startMethodTracing(traceName, fd, bufferSize, flags, false, 0);
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07001056 }
1057
1058 /**
Andy McFadden72a20db0c2010-01-22 12:20:41 -08001059 * Starts method tracing without a backing file. When stopMethodTracing
1060 * is called, the result is sent directly to DDMS. (If DDMS is not
1061 * attached when tracing ends, the profiling data will be discarded.)
1062 *
1063 * @hide
1064 */
Jeff Hao7be3a132013-08-22 15:53:12 -07001065 public static void startMethodTracingDdms(int bufferSize, int flags,
1066 boolean samplingEnabled, int intervalUs) {
1067 VMDebug.startMethodTracingDdms(bufferSize, flags, samplingEnabled, intervalUs);
Andy McFadden72a20db0c2010-01-22 12:20:41 -08001068 }
1069
1070 /**
Jeff Haoac277052013-08-29 11:19:39 -07001071 * Determine whether method tracing is currently active and what type is
1072 * active.
1073 *
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -07001074 * @hide
1075 */
Jeff Haoac277052013-08-29 11:19:39 -07001076 public static int getMethodTracingMode() {
1077 return VMDebug.getMethodTracingMode();
The Android Open Source Project7b0b1ed2009-03-18 22:20:26 -07001078 }
1079
1080 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001081 * Stop method tracing.
1082 */
1083 public static void stopMethodTracing() {
1084 VMDebug.stopMethodTracing();
1085 }
1086
1087 /**
1088 * Get an indication of thread CPU usage. The value returned
1089 * indicates the amount of time that the current thread has spent
1090 * executing code or waiting for certain types of I/O.
1091 *
1092 * The time is expressed in nanoseconds, and is only meaningful
1093 * when compared to the result from an earlier call. Note that
1094 * nanosecond resolution does not imply nanosecond accuracy.
1095 *
1096 * On system which don't support this operation, the call returns -1.
1097 */
1098 public static long threadCpuTimeNanos() {
1099 return VMDebug.threadCpuTimeNanos();
1100 }
1101
1102 /**
Chet Haase2970c492010-11-09 13:58:04 -08001103 * Start counting the number and aggregate size of memory allocations.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001104 *
Ian Rogersfe067a42013-02-22 19:59:23 -08001105 * <p>The {@link #startAllocCounting() start} method resets the counts and enables counting.
1106 * The {@link #stopAllocCounting() stop} method disables the counting so that the analysis
1107 * code doesn't cause additional allocations. The various <code>get</code> methods return
1108 * the specified value. And the various <code>reset</code> methods reset the specified
Chet Haase2970c492010-11-09 13:58:04 -08001109 * count.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001110 *
Ian Rogersfe067a42013-02-22 19:59:23 -08001111 * <p>Counts are kept for the system as a whole (global) and for each thread.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001112 * The per-thread counts for threads other than the current thread
Chet Haase2970c492010-11-09 13:58:04 -08001113 * are not cleared by the "reset" or "start" calls.</p>
Ian Rogersfe067a42013-02-22 19:59:23 -08001114 *
1115 * @deprecated Accurate counting is a burden on the runtime and may be removed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001116 */
Ian Rogersfe067a42013-02-22 19:59:23 -08001117 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001118 public static void startAllocCounting() {
1119 VMDebug.startAllocCounting();
1120 }
Chet Haase2970c492010-11-09 13:58:04 -08001121
1122 /**
1123 * Stop counting the number and aggregate size of memory allocations.
1124 *
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001125 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Chet Haase2970c492010-11-09 13:58:04 -08001126 */
Ian Rogersc2a3adb2013-04-19 11:31:48 -07001127 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001128 public static void stopAllocCounting() {
1129 VMDebug.stopAllocCounting();
1130 }
1131
Ian Rogersfe067a42013-02-22 19:59:23 -08001132 /**
1133 * Returns the global count of objects allocated by the runtime between a
1134 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001135 *
1136 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001137 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001138 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001139 public static int getGlobalAllocCount() {
1140 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_OBJECTS);
1141 }
Ian Rogersfe067a42013-02-22 19:59:23 -08001142
1143 /**
1144 * Clears the global count of objects allocated.
1145 * @see #getGlobalAllocCount()
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001146 *
1147 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001148 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001149 @Deprecated
Ian Rogersfe067a42013-02-22 19:59:23 -08001150 public static void resetGlobalAllocCount() {
1151 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_OBJECTS);
1152 }
1153
1154 /**
1155 * Returns the global size, in bytes, of objects allocated by the runtime between a
1156 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001157 *
1158 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001159 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001160 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001161 public static int getGlobalAllocSize() {
1162 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_BYTES);
1163 }
Ian Rogersfe067a42013-02-22 19:59:23 -08001164
1165 /**
1166 * Clears the global size of objects allocated.
Dianne Hackborn3fa89692013-09-13 17:20:00 -07001167 * @see #getGlobalAllocSize()
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001168 *
1169 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001170 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001171 @Deprecated
Ian Rogersfe067a42013-02-22 19:59:23 -08001172 public static void resetGlobalAllocSize() {
1173 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_ALLOCATED_BYTES);
1174 }
1175
1176 /**
1177 * Returns the global count of objects freed by the runtime between a
1178 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001179 *
1180 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001181 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001182 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001183 public static int getGlobalFreedCount() {
1184 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_FREED_OBJECTS);
1185 }
Ian Rogersfe067a42013-02-22 19:59:23 -08001186
1187 /**
1188 * Clears the global count of objects freed.
1189 * @see #getGlobalFreedCount()
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001190 *
1191 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001192 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001193 @Deprecated
Ian Rogersfe067a42013-02-22 19:59:23 -08001194 public static void resetGlobalFreedCount() {
1195 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_FREED_OBJECTS);
1196 }
1197
1198 /**
1199 * Returns the global size, in bytes, of objects freed by the runtime between a
1200 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001201 *
1202 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001203 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001204 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001205 public static int getGlobalFreedSize() {
1206 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_FREED_BYTES);
1207 }
Ian Rogersfe067a42013-02-22 19:59:23 -08001208
1209 /**
1210 * Clears the global size of objects freed.
1211 * @see #getGlobalFreedSize()
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001212 *
1213 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001214 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001215 @Deprecated
Ian Rogersfe067a42013-02-22 19:59:23 -08001216 public static void resetGlobalFreedSize() {
1217 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_FREED_BYTES);
1218 }
1219
1220 /**
1221 * Returns the number of non-concurrent GC invocations between a
1222 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001223 *
1224 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001225 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001226 @Deprecated
Ian Rogersfe067a42013-02-22 19:59:23 -08001227 public static int getGlobalGcInvocationCount() {
1228 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_GC_INVOCATIONS);
1229 }
1230
1231 /**
1232 * Clears the count of non-concurrent GC invocations.
1233 * @see #getGlobalGcInvocationCount()
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001234 *
1235 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001236 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001237 @Deprecated
Ian Rogersfe067a42013-02-22 19:59:23 -08001238 public static void resetGlobalGcInvocationCount() {
1239 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_GC_INVOCATIONS);
1240 }
1241
1242 /**
1243 * Returns the number of classes successfully initialized (ie those that executed without
1244 * throwing an exception) between a {@link #startAllocCounting() start} and
1245 * {@link #stopAllocCounting() stop}.
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001246 *
1247 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001248 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001249 @Deprecated
Andy McFaddenc4e1bf72010-02-22 17:07:36 -08001250 public static int getGlobalClassInitCount() {
Andy McFaddenc4e1bf72010-02-22 17:07:36 -08001251 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_COUNT);
1252 }
Ian Rogersfe067a42013-02-22 19:59:23 -08001253
1254 /**
1255 * Clears the count of classes initialized.
1256 * @see #getGlobalClassInitCount()
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001257 *
1258 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001259 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001260 @Deprecated
Ian Rogersfe067a42013-02-22 19:59:23 -08001261 public static void resetGlobalClassInitCount() {
1262 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_COUNT);
1263 }
1264
1265 /**
1266 * Returns the time spent successfully initializing classes between a
1267 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001268 *
1269 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001270 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001271 @Deprecated
Andy McFaddenc4e1bf72010-02-22 17:07:36 -08001272 public static int getGlobalClassInitTime() {
1273 /* cumulative elapsed time for class initialization, in usec */
1274 return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_TIME);
1275 }
Carl Shapirob5961982010-12-22 15:54:53 -08001276
1277 /**
Ian Rogersfe067a42013-02-22 19:59:23 -08001278 * Clears the count of time spent initializing classes.
1279 * @see #getGlobalClassInitTime()
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001280 *
1281 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001282 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001283 @Deprecated
Ian Rogersfe067a42013-02-22 19:59:23 -08001284 public static void resetGlobalClassInitTime() {
1285 VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_TIME);
1286 }
1287
1288 /**
Carl Shapiro7e942842011-01-12 17:17:45 -08001289 * This method exists for compatibility and always returns 0.
Carl Shapirob5961982010-12-22 15:54:53 -08001290 * @deprecated This method is now obsolete.
1291 */
1292 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001293 public static int getGlobalExternalAllocCount() {
Carl Shapirob5961982010-12-22 15:54:53 -08001294 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001295 }
Carl Shapirob5961982010-12-22 15:54:53 -08001296
1297 /**
Ian Rogersfe067a42013-02-22 19:59:23 -08001298 * This method exists for compatibility and has no effect.
1299 * @deprecated This method is now obsolete.
1300 */
1301 @Deprecated
1302 public static void resetGlobalExternalAllocSize() {}
1303
1304 /**
1305 * This method exists for compatibility and has no effect.
1306 * @deprecated This method is now obsolete.
1307 */
1308 @Deprecated
1309 public static void resetGlobalExternalAllocCount() {}
1310
1311 /**
Carl Shapiro7e942842011-01-12 17:17:45 -08001312 * This method exists for compatibility and always returns 0.
Carl Shapirob5961982010-12-22 15:54:53 -08001313 * @deprecated This method is now obsolete.
1314 */
1315 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001316 public static int getGlobalExternalAllocSize() {
Carl Shapirob5961982010-12-22 15:54:53 -08001317 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001318 }
Carl Shapirob5961982010-12-22 15:54:53 -08001319
1320 /**
Ian Rogersfe067a42013-02-22 19:59:23 -08001321 * This method exists for compatibility and always returns 0.
Carl Shapirob5961982010-12-22 15:54:53 -08001322 * @deprecated This method is now obsolete.
1323 */
1324 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001325 public static int getGlobalExternalFreedCount() {
Carl Shapirob5961982010-12-22 15:54:53 -08001326 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001327 }
Carl Shapirob5961982010-12-22 15:54:53 -08001328
1329 /**
Ian Rogersfe067a42013-02-22 19:59:23 -08001330 * This method exists for compatibility and has no effect.
1331 * @deprecated This method is now obsolete.
1332 */
1333 @Deprecated
1334 public static void resetGlobalExternalFreedCount() {}
1335
1336 /**
1337 * This method exists for compatibility and has no effect.
Carl Shapirob5961982010-12-22 15:54:53 -08001338 * @deprecated This method is now obsolete.
1339 */
1340 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001341 public static int getGlobalExternalFreedSize() {
Carl Shapirob5961982010-12-22 15:54:53 -08001342 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001343 }
Carl Shapirob5961982010-12-22 15:54:53 -08001344
Ian Rogersfe067a42013-02-22 19:59:23 -08001345 /**
1346 * This method exists for compatibility and has no effect.
1347 * @deprecated This method is now obsolete.
1348 */
1349 @Deprecated
1350 public static void resetGlobalExternalFreedSize() {}
1351
1352 /**
1353 * Returns the thread-local count of objects allocated by the runtime between a
1354 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001355 *
1356 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001357 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001358 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001359 public static int getThreadAllocCount() {
1360 return VMDebug.getAllocCount(VMDebug.KIND_THREAD_ALLOCATED_OBJECTS);
1361 }
Ian Rogersfe067a42013-02-22 19:59:23 -08001362
1363 /**
1364 * Clears the thread-local count of objects allocated.
1365 * @see #getThreadAllocCount()
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001366 *
1367 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001368 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001369 @Deprecated
Ian Rogersfe067a42013-02-22 19:59:23 -08001370 public static void resetThreadAllocCount() {
1371 VMDebug.resetAllocCount(VMDebug.KIND_THREAD_ALLOCATED_OBJECTS);
1372 }
1373
1374 /**
1375 * Returns the thread-local size of objects allocated by the runtime between a
1376 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
1377 * @return The allocated size in bytes.
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001378 *
1379 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001380 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001381 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382 public static int getThreadAllocSize() {
1383 return VMDebug.getAllocCount(VMDebug.KIND_THREAD_ALLOCATED_BYTES);
1384 }
Carl Shapirob5961982010-12-22 15:54:53 -08001385
1386 /**
Ian Rogersfe067a42013-02-22 19:59:23 -08001387 * Clears the thread-local count of objects allocated.
1388 * @see #getThreadAllocSize()
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001389 *
1390 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001391 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001392 @Deprecated
Ian Rogersfe067a42013-02-22 19:59:23 -08001393 public static void resetThreadAllocSize() {
1394 VMDebug.resetAllocCount(VMDebug.KIND_THREAD_ALLOCATED_BYTES);
1395 }
1396
1397 /**
1398 * This method exists for compatibility and has no effect.
Carl Shapirob5961982010-12-22 15:54:53 -08001399 * @deprecated This method is now obsolete.
1400 */
1401 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001402 public static int getThreadExternalAllocCount() {
Carl Shapirob5961982010-12-22 15:54:53 -08001403 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001404 }
Carl Shapirob5961982010-12-22 15:54:53 -08001405
1406 /**
Ian Rogersfe067a42013-02-22 19:59:23 -08001407 * This method exists for compatibility and has no effect.
1408 * @deprecated This method is now obsolete.
1409 */
1410 @Deprecated
1411 public static void resetThreadExternalAllocCount() {}
1412
1413 /**
1414 * This method exists for compatibility and has no effect.
Carl Shapirob5961982010-12-22 15:54:53 -08001415 * @deprecated This method is now obsolete.
1416 */
1417 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001418 public static int getThreadExternalAllocSize() {
Carl Shapirob5961982010-12-22 15:54:53 -08001419 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001420 }
Carl Shapirob5961982010-12-22 15:54:53 -08001421
Carl Shapirob5961982010-12-22 15:54:53 -08001422 /**
Carl Shapiro7e942842011-01-12 17:17:45 -08001423 * This method exists for compatibility and has no effect.
Carl Shapirob5961982010-12-22 15:54:53 -08001424 * @deprecated This method is now obsolete.
1425 */
1426 @Deprecated
1427 public static void resetThreadExternalAllocSize() {}
1428
Ian Rogersfe067a42013-02-22 19:59:23 -08001429 /**
1430 * Returns the number of thread-local non-concurrent GC invocations between a
1431 * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001432 *
1433 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001434 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001435 @Deprecated
Ian Rogersfe067a42013-02-22 19:59:23 -08001436 public static int getThreadGcInvocationCount() {
1437 return VMDebug.getAllocCount(VMDebug.KIND_THREAD_GC_INVOCATIONS);
1438 }
1439
1440 /**
1441 * Clears the thread-local count of non-concurrent GC invocations.
1442 * @see #getThreadGcInvocationCount()
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001443 *
1444 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001445 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001446 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001447 public static void resetThreadGcInvocationCount() {
1448 VMDebug.resetAllocCount(VMDebug.KIND_THREAD_GC_INVOCATIONS);
1449 }
Ian Rogersfe067a42013-02-22 19:59:23 -08001450
1451 /**
1452 * Clears all the global and thread-local memory allocation counters.
1453 * @see #startAllocCounting()
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001454 *
1455 * @deprecated Accurate counting is a burden on the runtime and may be removed.
Ian Rogersfe067a42013-02-22 19:59:23 -08001456 */
Hiroshi Yamauchi172da262015-03-04 12:29:19 -08001457 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001458 public static void resetAllCounts() {
1459 VMDebug.resetAllocCount(VMDebug.KIND_ALL_COUNTS);
1460 }
1461
1462 /**
Hiroshi Yamauchi8b5a293d2015-04-02 12:26:10 -07001463 * Returns the value of a particular runtime statistic or {@code null} if no
1464 * such runtime statistic exists.
1465 *
1466 * <p>The following table lists the runtime statistics that the runtime supports.
1467 * Note runtime statistics may be added or removed in a future API level.</p>
1468 *
1469 * <table>
1470 * <thead>
1471 * <tr>
1472 * <th>Runtime statistic name</th>
1473 * <th>Meaning</th>
1474 * <th>Example</th>
1475 * <th>Supported (API Levels)</th>
1476 * </tr>
1477 * </thead>
1478 * <tbody>
1479 * <tr>
1480 * <td>art.gc.gc-count</td>
1481 * <td>The number of garbage collection runs.</td>
1482 * <td>{@code 164}</td>
1483 * <td>23</td>
1484 * </tr>
1485 * <tr>
1486 * <td>art.gc.gc-time</td>
1487 * <td>The total duration of garbage collection runs in ms.</td>
1488 * <td>{@code 62364}</td>
1489 * <td>23</td>
1490 * </tr>
1491 * <tr>
1492 * <td>art.gc.bytes-allocated</td>
1493 * <td>The total number of bytes that the application allocated.</td>
1494 * <td>{@code 1463948408}</td>
1495 * <td>23</td>
1496 * </tr>
1497 * <tr>
1498 * <td>art.gc.bytes-freed</td>
1499 * <td>The total number of bytes that garbage collection reclaimed.</td>
1500 * <td>{@code 1313493084}</td>
1501 * <td>23</td>
1502 * </tr>
1503 * <tr>
1504 * <td>art.gc.blocking-gc-count</td>
1505 * <td>The number of blocking garbage collection runs.</td>
1506 * <td>{@code 2}</td>
1507 * <td>23</td>
1508 * </tr>
1509 * <tr>
1510 * <td>art.gc.blocking-gc-time</td>
1511 * <td>The total duration of blocking garbage collection runs in ms.</td>
1512 * <td>{@code 804}</td>
1513 * <td>23</td>
1514 * </tr>
1515 * <tr>
1516 * <td>art.gc.gc-count-rate-histogram</td>
Hiroshi Yamauchi2d6327d2015-05-28 15:28:16 -07001517 * <td>Every 10 seconds, the gc-count-rate is computed as the number of garbage
1518 * collection runs that have occurred over the last 10
1519 * seconds. art.gc.gc-count-rate-histogram is a histogram of the gc-count-rate
1520 * samples taken since the process began. The histogram can be used to identify
1521 * instances of high rates of garbage collection runs. For example, a histogram
1522 * of "0:34503,1:45350,2:11281,3:8088,4:43,5:8" shows that most of the time
1523 * there are between 0 and 2 garbage collection runs every 10 seconds, but there
1524 * were 8 distinct 10-second intervals in which 5 garbage collection runs
1525 * occurred.</td>
Hiroshi Yamauchi8b5a293d2015-04-02 12:26:10 -07001526 * <td>{@code 0:34503,1:45350,2:11281,3:8088,4:43,5:8}</td>
1527 * <td>23</td>
1528 * </tr>
1529 * <tr>
1530 * <td>art.gc.blocking-gc-count-rate-histogram</td>
Hiroshi Yamauchi2d6327d2015-05-28 15:28:16 -07001531 * <td>Every 10 seconds, the blocking-gc-count-rate is computed as the number of
1532 * blocking garbage collection runs that have occurred over the last 10
1533 * seconds. art.gc.blocking-gc-count-rate-histogram is a histogram of the
1534 * blocking-gc-count-rate samples taken since the process began. The histogram
1535 * can be used to identify instances of high rates of blocking garbage
1536 * collection runs. For example, a histogram of "0:99269,1:1,2:1" shows that
1537 * most of the time there are zero blocking garbage collection runs every 10
1538 * seconds, but there was one 10-second interval in which one blocking garbage
1539 * collection run occurred, and there was one interval in which two blocking
1540 * garbage collection runs occurred.</td>
Hiroshi Yamauchi8b5a293d2015-04-02 12:26:10 -07001541 * <td>{@code 0:99269,1:1,2:1}</td>
1542 * <td>23</td>
1543 * </tr>
1544 * </tbody>
1545 * </table>
1546 *
1547 * @param statName
1548 * the name of the runtime statistic to look up.
1549 * @return the value of the specified runtime statistic or {@code null} if the
1550 * runtime statistic doesn't exist.
Hiroshi Yamauchi8b5a293d2015-04-02 12:26:10 -07001551 */
1552 public static String getRuntimeStat(String statName) {
1553 return VMDebug.getRuntimeStat(statName);
1554 }
1555
1556 /**
1557 * Returns a map of the names/values of the runtime statistics
Hiroshi Yamauchid8001672015-04-14 16:07:26 -07001558 * that {@link #getRuntimeStat(String)} supports.
Hiroshi Yamauchi8b5a293d2015-04-02 12:26:10 -07001559 *
1560 * @return a map of the names/values of the supported runtime statistics.
Hiroshi Yamauchi8b5a293d2015-04-02 12:26:10 -07001561 */
1562 public static Map<String, String> getRuntimeStats() {
1563 return VMDebug.getRuntimeStats();
1564 }
1565
1566 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001567 * Returns the size of the native heap.
1568 * @return The size of the native heap in bytes.
1569 */
1570 public static native long getNativeHeapSize();
1571
1572 /**
1573 * Returns the amount of allocated memory in the native heap.
1574 * @return The allocated size in bytes.
1575 */
1576 public static native long getNativeHeapAllocatedSize();
1577
1578 /**
1579 * Returns the amount of free memory in the native heap.
1580 * @return The freed size in bytes.
1581 */
1582 public static native long getNativeHeapFreeSize();
1583
1584 /**
1585 * Retrieves information about this processes memory usages. This information is broken down by
Dianne Hackbornb02ce292015-10-12 15:14:16 -07001586 * how much is in use by dalvik, the native heap, and everything else.
1587 *
1588 * <p><b>Note:</b> this method directly retrieves memory information for the give process
1589 * from low-level data available to it. It may not be able to retrieve information about
1590 * some protected allocations, such as graphics. If you want to be sure you can see
1591 * all information about allocations by the process, use instead
1592 * {@link android.app.ActivityManager#getProcessMemoryInfo(int[])}.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001593 */
1594 public static native void getMemoryInfo(MemoryInfo memoryInfo);
1595
1596 /**
Dianne Hackborn3025ef32009-08-31 21:31:47 -07001597 * Note: currently only works when the requested pid has the same UID
1598 * as the caller.
1599 * @hide
1600 */
1601 public static native void getMemoryInfo(int pid, MemoryInfo memoryInfo);
1602
1603 /**
Dianne Hackbornb437e092011-08-05 17:50:29 -07001604 * Retrieves the PSS memory used by the process as given by the
1605 * smaps.
1606 */
1607 public static native long getPss();
1608
1609 /**
1610 * Retrieves the PSS memory used by the process as given by the
Martijn Coenene0764852016-01-07 17:04:22 -08001611 * smaps. Optionally supply a long array of 2 entries to also
1612 * receive the Uss and SwapPss of the process, and another array to also
1613 * retrieve the separate memtrack size.
1614 * @hide
Dianne Hackbornb437e092011-08-05 17:50:29 -07001615 */
Martijn Coenene0764852016-01-07 17:04:22 -08001616 public static native long getPss(int pid, long[] outUssSwapPss, long[] outMemtrack);
Dianne Hackbornb437e092011-08-05 17:50:29 -07001617
Dianne Hackborn8e692572013-09-10 19:06:15 -07001618 /** @hide */
1619 public static final int MEMINFO_TOTAL = 0;
1620 /** @hide */
1621 public static final int MEMINFO_FREE = 1;
1622 /** @hide */
1623 public static final int MEMINFO_BUFFERS = 2;
1624 /** @hide */
1625 public static final int MEMINFO_CACHED = 3;
1626 /** @hide */
1627 public static final int MEMINFO_SHMEM = 4;
1628 /** @hide */
1629 public static final int MEMINFO_SLAB = 5;
1630 /** @hide */
Dianne Hackborncbd9a522013-09-24 23:10:14 -07001631 public static final int MEMINFO_SWAP_TOTAL = 6;
1632 /** @hide */
1633 public static final int MEMINFO_SWAP_FREE = 7;
1634 /** @hide */
1635 public static final int MEMINFO_ZRAM_TOTAL = 8;
1636 /** @hide */
Dianne Hackbornb3af4ec2014-10-17 15:25:13 -07001637 public static final int MEMINFO_MAPPED = 9;
1638 /** @hide */
1639 public static final int MEMINFO_VM_ALLOC_USED = 10;
1640 /** @hide */
1641 public static final int MEMINFO_PAGE_TABLES = 11;
1642 /** @hide */
1643 public static final int MEMINFO_KERNEL_STACK = 12;
1644 /** @hide */
1645 public static final int MEMINFO_COUNT = 13;
Dianne Hackborn8e692572013-09-10 19:06:15 -07001646
1647 /**
1648 * Retrieves /proc/meminfo. outSizes is filled with fields
1649 * as defined by MEMINFO_* offsets.
1650 * @hide
1651 */
1652 public static native void getMemInfo(long[] outSizes);
1653
Dianne Hackbornb437e092011-08-05 17:50:29 -07001654 /**
Carl Shapiro11073832011-01-12 16:28:57 -08001655 * Establish an object allocation limit in the current thread.
Carl Shapiro7e942842011-01-12 17:17:45 -08001656 * This feature was never enabled in release builds. The
1657 * allocation limits feature was removed in Honeycomb. This
1658 * method exists for compatibility and always returns -1 and has
1659 * no effect.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001660 *
Carl Shapiro11073832011-01-12 16:28:57 -08001661 * @deprecated This method is now obsolete.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001662 */
Carl Shapiro11073832011-01-12 16:28:57 -08001663 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001664 public static int setAllocationLimit(int limit) {
Carl Shapiro11073832011-01-12 16:28:57 -08001665 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001666 }
1667
1668 /**
Carl Shapiro11073832011-01-12 16:28:57 -08001669 * Establish a global object allocation limit. This feature was
Carl Shapiro7e942842011-01-12 17:17:45 -08001670 * never enabled in release builds. The allocation limits feature
1671 * was removed in Honeycomb. This method exists for compatibility
1672 * and always returns -1 and has no effect.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001673 *
Carl Shapiro11073832011-01-12 16:28:57 -08001674 * @deprecated This method is now obsolete.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001675 */
Carl Shapiro11073832011-01-12 16:28:57 -08001676 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001677 public static int setGlobalAllocationLimit(int limit) {
Carl Shapiro11073832011-01-12 16:28:57 -08001678 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001679 }
1680
1681 /**
1682 * Dump a list of all currently loaded class to the log file.
1683 *
1684 * @param flags See constants above.
1685 */
1686 public static void printLoadedClasses(int flags) {
1687 VMDebug.printLoadedClasses(flags);
1688 }
1689
1690 /**
1691 * Get the number of loaded classes.
1692 * @return the number of loaded classes.
1693 */
1694 public static int getLoadedClassCount() {
1695 return VMDebug.getLoadedClassCount();
1696 }
1697
1698 /**
Andy McFadden824c5102010-07-09 16:26:57 -07001699 * Dump "hprof" data to the specified file. This may cause a GC.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001700 *
1701 * @param fileName Full pathname of output file (e.g. "/sdcard/dump.hprof").
1702 * @throws UnsupportedOperationException if the VM was built without
1703 * HPROF support.
1704 * @throws IOException if an error occurs while opening or writing files.
1705 */
1706 public static void dumpHprofData(String fileName) throws IOException {
1707 VMDebug.dumpHprofData(fileName);
1708 }
1709
1710 /**
Andy McFadden824c5102010-07-09 16:26:57 -07001711 * Like dumpHprofData(String), but takes an already-opened
1712 * FileDescriptor to which the trace is written. The file name is also
1713 * supplied simply for logging. Makes a dup of the file descriptor.
1714 *
1715 * Primarily for use by the "am" shell command.
1716 *
1717 * @hide
1718 */
1719 public static void dumpHprofData(String fileName, FileDescriptor fd)
1720 throws IOException {
1721 VMDebug.dumpHprofData(fileName, fd);
1722 }
1723
1724 /**
1725 * Collect "hprof" and send it to DDMS. This may cause a GC.
Andy McFadden07a96612010-01-28 16:54:37 -08001726 *
1727 * @throws UnsupportedOperationException if the VM was built without
1728 * HPROF support.
Andy McFadden07a96612010-01-28 16:54:37 -08001729 * @hide
1730 */
1731 public static void dumpHprofDataDdms() {
1732 VMDebug.dumpHprofDataDdms();
1733 }
1734
1735 /**
Andy McFadden06a6b552010-07-13 16:28:09 -07001736 * Writes native heap data to the specified file descriptor.
1737 *
1738 * @hide
1739 */
1740 public static native void dumpNativeHeap(FileDescriptor fd);
1741
1742 /**
Brian Carlstromc21550a2010-10-05 21:34:06 -07001743 * Returns a count of the extant instances of a class.
1744 *
1745 * @hide
1746 */
1747 public static long countInstancesOfClass(Class cls) {
Brian Carlstrom7495cfa2010-11-30 18:06:00 -08001748 return VMDebug.countInstancesOfClass(cls, true);
Brian Carlstromc21550a2010-10-05 21:34:06 -07001749 }
1750
1751 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001752 * Returns the number of sent transactions from this process.
1753 * @return The number of sent transactions or -1 if it could not read t.
1754 */
1755 public static native int getBinderSentTransactions();
1756
1757 /**
1758 * Returns the number of received transactions from the binder driver.
1759 * @return The number of received transactions or -1 if it could not read the stats.
1760 */
1761 public static native int getBinderReceivedTransactions();
1762
1763 /**
1764 * Returns the number of active local Binder objects that exist in the
1765 * current process.
1766 */
1767 public static final native int getBinderLocalObjectCount();
1768
1769 /**
1770 * Returns the number of references to remote proxy Binder objects that
1771 * exist in the current process.
1772 */
1773 public static final native int getBinderProxyObjectCount();
1774
1775 /**
1776 * Returns the number of death notification links to Binder objects that
1777 * exist in the current process.
1778 */
1779 public static final native int getBinderDeathObjectCount();
1780
1781 /**
Andy McFadden599c9182009-04-08 00:35:56 -07001782 * Primes the register map cache.
1783 *
1784 * Only works for classes in the bootstrap class loader. Does not
1785 * cause classes to be loaded if they're not already present.
1786 *
1787 * The classAndMethodDesc argument is a concatentation of the VM-internal
1788 * class descriptor, method name, and method descriptor. Examples:
1789 * Landroid/os/Looper;.loop:()V
1790 * Landroid/app/ActivityThread;.main:([Ljava/lang/String;)V
1791 *
1792 * @param classAndMethodDesc the method to prepare
1793 *
1794 * @hide
1795 */
1796 public static final boolean cacheRegisterMap(String classAndMethodDesc) {
1797 return VMDebug.cacheRegisterMap(classAndMethodDesc);
1798 }
1799
1800 /**
Andy McFaddenbfd6d482009-10-22 17:25:57 -07001801 * Dumps the contents of VM reference tables (e.g. JNI locals and
1802 * globals) to the log file.
1803 *
1804 * @hide
1805 */
1806 public static final void dumpReferenceTables() {
1807 VMDebug.dumpReferenceTables();
1808 }
1809
1810 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001811 * API for gathering and querying instruction counts.
1812 *
1813 * Example usage:
Chet Haase2970c492010-11-09 13:58:04 -08001814 * <pre>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001815 * Debug.InstructionCount icount = new Debug.InstructionCount();
1816 * icount.resetAndStart();
1817 * [... do lots of stuff ...]
1818 * if (icount.collect()) {
1819 * System.out.println("Total instructions executed: "
1820 * + icount.globalTotal());
1821 * System.out.println("Method invocations: "
1822 * + icount.globalMethodInvocations());
1823 * }
Chet Haase2970c492010-11-09 13:58:04 -08001824 * </pre>
Jeff Hao7d0b3d42014-09-17 15:45:05 -07001825 *
1826 * @deprecated Instruction counting is no longer supported.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001827 */
Jeff Hao7d0b3d42014-09-17 15:45:05 -07001828 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001829 public static class InstructionCount {
Dan Bornsteinb96f5892010-12-02 17:19:53 -08001830 private static final int NUM_INSTR =
1831 OpcodeInfo.MAXIMUM_PACKED_VALUE + 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001832
1833 private int[] mCounts;
1834
1835 public InstructionCount() {
1836 mCounts = new int[NUM_INSTR];
1837 }
1838
1839 /**
1840 * Reset counters and ensure counts are running. Counts may
1841 * have already been running.
1842 *
1843 * @return true if counting was started
1844 */
1845 public boolean resetAndStart() {
1846 try {
1847 VMDebug.startInstructionCounting();
1848 VMDebug.resetInstructionCount();
1849 } catch (UnsupportedOperationException uoe) {
1850 return false;
1851 }
1852 return true;
1853 }
1854
1855 /**
1856 * Collect instruction counts. May or may not stop the
1857 * counting process.
1858 */
1859 public boolean collect() {
1860 try {
1861 VMDebug.stopInstructionCounting();
1862 VMDebug.getInstructionCount(mCounts);
1863 } catch (UnsupportedOperationException uoe) {
1864 return false;
1865 }
1866 return true;
1867 }
1868
1869 /**
1870 * Return the total number of instructions executed globally (i.e. in
1871 * all threads).
1872 */
1873 public int globalTotal() {
1874 int count = 0;
Dan Bornstein1d99b062010-11-30 12:26:52 -08001875
1876 for (int i = 0; i < NUM_INSTR; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001877 count += mCounts[i];
Dan Bornstein1d99b062010-11-30 12:26:52 -08001878 }
1879
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001880 return count;
1881 }
1882
1883 /**
1884 * Return the total number of method-invocation instructions
1885 * executed globally.
1886 */
1887 public int globalMethodInvocations() {
1888 int count = 0;
1889
Dan Bornstein1d99b062010-11-30 12:26:52 -08001890 for (int i = 0; i < NUM_INSTR; i++) {
1891 if (OpcodeInfo.isInvoke(i)) {
1892 count += mCounts[i];
1893 }
1894 }
1895
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001896 return count;
1897 }
Dave Bort1ce5bd32009-04-22 17:36:56 -07001898 }
1899
Dave Bort1ce5bd32009-04-22 17:36:56 -07001900 /**
1901 * A Map of typed debug properties.
1902 */
1903 private static final TypedProperties debugProperties;
1904
1905 /*
1906 * Load the debug properties from the standard files into debugProperties.
1907 */
1908 static {
Joe Onorato43a17652011-04-06 19:22:23 -07001909 if (false) {
Dave Bort1ce5bd32009-04-22 17:36:56 -07001910 final String TAG = "DebugProperties";
1911 final String[] files = { "/system/debug.prop", "/debug.prop", "/data/debug.prop" };
1912 final TypedProperties tp = new TypedProperties();
1913
1914 // Read the properties from each of the files, if present.
Dave Borte9bfd9b2009-05-04 14:35:23 -07001915 for (String file : files) {
Dave Bort1ce5bd32009-04-22 17:36:56 -07001916 Reader r;
1917 try {
1918 r = new FileReader(file);
1919 } catch (FileNotFoundException ex) {
1920 // It's ok if a file is missing.
1921 continue;
1922 }
1923
Dave Bort1ce5bd32009-04-22 17:36:56 -07001924 try {
1925 tp.load(r);
Dave Borte9bfd9b2009-05-04 14:35:23 -07001926 } catch (Exception ex) {
1927 throw new RuntimeException("Problem loading " + file, ex);
1928 } finally {
1929 try {
1930 r.close();
1931 } catch (IOException ex) {
1932 // Ignore this error.
1933 }
Dave Bort1ce5bd32009-04-22 17:36:56 -07001934 }
1935 }
1936
1937 debugProperties = tp.isEmpty() ? null : tp;
1938 } else {
1939 debugProperties = null;
1940 }
1941 }
1942
1943
1944 /**
1945 * Returns true if the type of the field matches the specified class.
1946 * Handles the case where the class is, e.g., java.lang.Boolean, but
1947 * the field is of the primitive "boolean" type. Also handles all of
1948 * the java.lang.Number subclasses.
1949 */
1950 private static boolean fieldTypeMatches(Field field, Class<?> cl) {
1951 Class<?> fieldClass = field.getType();
1952 if (fieldClass == cl) {
1953 return true;
1954 }
1955 Field primitiveTypeField;
1956 try {
1957 /* All of the classes we care about (Boolean, Integer, etc.)
1958 * have a Class field called "TYPE" that points to the corresponding
1959 * primitive class.
1960 */
1961 primitiveTypeField = cl.getField("TYPE");
1962 } catch (NoSuchFieldException ex) {
1963 return false;
1964 }
1965 try {
Dave Borte9bfd9b2009-05-04 14:35:23 -07001966 return fieldClass == (Class<?>) primitiveTypeField.get(null);
Dave Bort1ce5bd32009-04-22 17:36:56 -07001967 } catch (IllegalAccessException ex) {
1968 return false;
1969 }
1970 }
1971
1972
1973 /**
1974 * Looks up the property that corresponds to the field, and sets the field's value
1975 * if the types match.
1976 */
Dave Borte9bfd9b2009-05-04 14:35:23 -07001977 private static void modifyFieldIfSet(final Field field, final TypedProperties properties,
1978 final String propertyName) {
Dave Bort1ce5bd32009-04-22 17:36:56 -07001979 if (field.getType() == java.lang.String.class) {
Dave Borte9bfd9b2009-05-04 14:35:23 -07001980 int stringInfo = properties.getStringInfo(propertyName);
Dave Bort1ce5bd32009-04-22 17:36:56 -07001981 switch (stringInfo) {
Dave Borte9bfd9b2009-05-04 14:35:23 -07001982 case TypedProperties.STRING_SET:
1983 // Handle as usual below.
1984 break;
1985 case TypedProperties.STRING_NULL:
1986 try {
1987 field.set(null, null); // null object for static fields; null string
1988 } catch (IllegalAccessException ex) {
1989 throw new IllegalArgumentException(
1990 "Cannot set field for " + propertyName, ex);
1991 }
1992 return;
1993 case TypedProperties.STRING_NOT_SET:
1994 return;
1995 case TypedProperties.STRING_TYPE_MISMATCH:
Dave Bort1ce5bd32009-04-22 17:36:56 -07001996 throw new IllegalArgumentException(
Dave Borte9bfd9b2009-05-04 14:35:23 -07001997 "Type of " + propertyName + " " +
1998 " does not match field type (" + field.getType() + ")");
1999 default:
2000 throw new IllegalStateException(
2001 "Unexpected getStringInfo(" + propertyName + ") return value " +
2002 stringInfo);
Dave Bort1ce5bd32009-04-22 17:36:56 -07002003 }
2004 }
Dave Borte9bfd9b2009-05-04 14:35:23 -07002005 Object value = properties.get(propertyName);
Dave Bort1ce5bd32009-04-22 17:36:56 -07002006 if (value != null) {
2007 if (!fieldTypeMatches(field, value.getClass())) {
2008 throw new IllegalArgumentException(
2009 "Type of " + propertyName + " (" + value.getClass() + ") " +
2010 " does not match field type (" + field.getType() + ")");
2011 }
2012 try {
2013 field.set(null, value); // null object for static fields
2014 } catch (IllegalAccessException ex) {
2015 throw new IllegalArgumentException(
2016 "Cannot set field for " + propertyName, ex);
2017 }
2018 }
2019 }
2020
2021
2022 /**
Romain Guyc4b11a72009-05-13 15:46:37 -07002023 * Equivalent to <code>setFieldsOn(cl, false)</code>.
2024 *
2025 * @see #setFieldsOn(Class, boolean)
Romain Guyd4103d02009-05-14 12:24:21 -07002026 *
2027 * @hide
Romain Guyc4b11a72009-05-13 15:46:37 -07002028 */
2029 public static void setFieldsOn(Class<?> cl) {
2030 setFieldsOn(cl, false);
2031 }
2032
2033 /**
Dave Bort1ce5bd32009-04-22 17:36:56 -07002034 * Reflectively sets static fields of a class based on internal debugging
Joe Onorato43a17652011-04-06 19:22:23 -07002035 * properties. This method is a no-op if false is
Dave Bort1ce5bd32009-04-22 17:36:56 -07002036 * false.
2037 * <p>
Joe Onorato43a17652011-04-06 19:22:23 -07002038 * <strong>NOTE TO APPLICATION DEVELOPERS</strong>: false will
Dave Bort1ce5bd32009-04-22 17:36:56 -07002039 * always be false in release builds. This API is typically only useful
2040 * for platform developers.
2041 * </p>
2042 * Class setup: define a class whose only fields are non-final, static
2043 * primitive types (except for "char") or Strings. In a static block
2044 * after the field definitions/initializations, pass the class to
Romain Guyc4b11a72009-05-13 15:46:37 -07002045 * this method, Debug.setFieldsOn(). Example:
Dave Bort1ce5bd32009-04-22 17:36:56 -07002046 * <pre>
2047 * package com.example;
2048 *
2049 * import android.os.Debug;
2050 *
2051 * public class MyDebugVars {
2052 * public static String s = "a string";
2053 * public static String s2 = "second string";
2054 * public static String ns = null;
2055 * public static boolean b = false;
2056 * public static int i = 5;
Romain Guyc4b11a72009-05-13 15:46:37 -07002057 * @Debug.DebugProperty
Dave Bort1ce5bd32009-04-22 17:36:56 -07002058 * public static float f = 0.1f;
Romain Guyc4b11a72009-05-13 15:46:37 -07002059 * @@Debug.DebugProperty
Dave Bort1ce5bd32009-04-22 17:36:56 -07002060 * public static double d = 0.5d;
2061 *
2062 * // This MUST appear AFTER all fields are defined and initialized!
2063 * static {
Romain Guyc4b11a72009-05-13 15:46:37 -07002064 * // Sets all the fields
Dave Borte9bfd9b2009-05-04 14:35:23 -07002065 * Debug.setFieldsOn(MyDebugVars.class);
Christian Mehlmauer798e2d32010-06-17 18:24:07 +02002066 *
Romain Guyc4b11a72009-05-13 15:46:37 -07002067 * // Sets only the fields annotated with @Debug.DebugProperty
2068 * // Debug.setFieldsOn(MyDebugVars.class, true);
Dave Bort1ce5bd32009-04-22 17:36:56 -07002069 * }
2070 * }
2071 * </pre>
Dave Borte9bfd9b2009-05-04 14:35:23 -07002072 * setFieldsOn() may override the value of any field in the class based
Dave Bort1ce5bd32009-04-22 17:36:56 -07002073 * on internal properties that are fixed at boot time.
2074 * <p>
2075 * These properties are only set during platform debugging, and are not
2076 * meant to be used as a general-purpose properties store.
2077 *
2078 * {@hide}
2079 *
2080 * @param cl The class to (possibly) modify
Romain Guyc4b11a72009-05-13 15:46:37 -07002081 * @param partial If false, sets all static fields, otherwise, only set
2082 * fields with the {@link android.os.Debug.DebugProperty}
2083 * annotation
Dave Bort1ce5bd32009-04-22 17:36:56 -07002084 * @throws IllegalArgumentException if any fields are final or non-static,
2085 * or if the type of the field does not match the type of
2086 * the internal debugging property value.
2087 */
Romain Guyc4b11a72009-05-13 15:46:37 -07002088 public static void setFieldsOn(Class<?> cl, boolean partial) {
Joe Onorato43a17652011-04-06 19:22:23 -07002089 if (false) {
Dave Bort1ce5bd32009-04-22 17:36:56 -07002090 if (debugProperties != null) {
2091 /* Only look for fields declared directly by the class,
2092 * so we don't mysteriously change static fields in superclasses.
2093 */
2094 for (Field field : cl.getDeclaredFields()) {
Romain Guyc4b11a72009-05-13 15:46:37 -07002095 if (!partial || field.getAnnotation(DebugProperty.class) != null) {
2096 final String propertyName = cl.getName() + "." + field.getName();
2097 boolean isStatic = Modifier.isStatic(field.getModifiers());
2098 boolean isFinal = Modifier.isFinal(field.getModifiers());
2099
2100 if (!isStatic || isFinal) {
2101 throw new IllegalArgumentException(propertyName +
2102 " must be static and non-final");
2103 }
2104 modifyFieldIfSet(field, debugProperties, propertyName);
Dave Bort1ce5bd32009-04-22 17:36:56 -07002105 }
Dave Bort1ce5bd32009-04-22 17:36:56 -07002106 }
2107 }
2108 } else {
Dan Egnor3eda9792010-03-05 13:28:36 -08002109 Log.wtf(TAG,
Dave Borte9bfd9b2009-05-04 14:35:23 -07002110 "setFieldsOn(" + (cl == null ? "null" : cl.getName()) +
Dave Bort1ce5bd32009-04-22 17:36:56 -07002111 ") called in non-DEBUG build");
2112 }
2113 }
Romain Guyc4b11a72009-05-13 15:46:37 -07002114
2115 /**
2116 * Annotation to put on fields you want to set with
2117 * {@link Debug#setFieldsOn(Class, boolean)}.
2118 *
2119 * @hide
2120 */
2121 @Target({ ElementType.FIELD })
2122 @Retention(RetentionPolicy.RUNTIME)
2123 public @interface DebugProperty {
2124 }
Dan Egnor3eda9792010-03-05 13:28:36 -08002125
2126 /**
2127 * Get a debugging dump of a system service by name.
2128 *
2129 * <p>Most services require the caller to hold android.permission.DUMP.
2130 *
2131 * @param name of the service to dump
2132 * @param fd to write dump output to (usually an output log file)
2133 * @param args to pass to the service's dump method, may be null
2134 * @return true if the service was dumped successfully, false if
2135 * the service could not be found or had an error while dumping
2136 */
2137 public static boolean dumpService(String name, FileDescriptor fd, String[] args) {
2138 IBinder service = ServiceManager.getService(name);
2139 if (service == null) {
2140 Log.e(TAG, "Can't find service to dump: " + name);
2141 return false;
2142 }
2143
2144 try {
2145 service.dump(fd, args);
2146 return true;
2147 } catch (RemoteException e) {
2148 Log.e(TAG, "Can't dump service: " + name, e);
2149 return false;
2150 }
2151 }
Craig Mautnera51a9562012-04-17 17:05:26 -07002152
2153 /**
Dianne Hackbornf72467a2012-06-08 17:23:59 -07002154 * Have the stack traces of the given native process dumped to the
2155 * specified file. Will be appended to the file.
2156 * @hide
2157 */
2158 public static native void dumpNativeBacktraceToFile(int pid, String file);
2159
2160 /**
Craig Mautnera51a9562012-04-17 17:05:26 -07002161 * Return a String describing the calling method and location at a particular stack depth.
Anwar Ghuloum3a8ce1b2013-04-26 16:18:28 -07002162 * @param callStack the Thread stack
Craig Mautnera51a9562012-04-17 17:05:26 -07002163 * @param depth the depth of stack to return information for.
2164 * @return the String describing the caller at that depth.
2165 */
2166 private static String getCaller(StackTraceElement callStack[], int depth) {
2167 // callStack[4] is the caller of the method that called getCallers()
2168 if (4 + depth >= callStack.length) {
2169 return "<bottom of call stack>";
2170 }
2171 StackTraceElement caller = callStack[4 + depth];
2172 return caller.getClassName() + "." + caller.getMethodName() + ":" + caller.getLineNumber();
2173 }
2174
2175 /**
2176 * Return a string consisting of methods and locations at multiple call stack levels.
2177 * @param depth the number of levels to return, starting with the immediate caller.
2178 * @return a string describing the call stack.
2179 * {@hide}
2180 */
2181 public static String getCallers(final int depth) {
2182 final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
2183 StringBuffer sb = new StringBuffer();
2184 for (int i = 0; i < depth; i++) {
2185 sb.append(getCaller(callStack, i)).append(" ");
2186 }
2187 return sb.toString();
2188 }
2189
2190 /**
Dianne Hackbornfd6c7b12013-10-03 10:42:26 -07002191 * Return a string consisting of methods and locations at multiple call stack levels.
2192 * @param depth the number of levels to return, starting with the immediate caller.
2193 * @return a string describing the call stack.
2194 * {@hide}
2195 */
2196 public static String getCallers(final int start, int depth) {
2197 final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
2198 StringBuffer sb = new StringBuffer();
2199 depth += start;
2200 for (int i = start; i < depth; i++) {
2201 sb.append(getCaller(callStack, i)).append(" ");
2202 }
2203 return sb.toString();
2204 }
2205
2206 /**
Dianne Hackbornef03a7f2012-10-29 18:46:52 -07002207 * Like {@link #getCallers(int)}, but each location is append to the string
2208 * as a new line with <var>linePrefix</var> in front of it.
2209 * @param depth the number of levels to return, starting with the immediate caller.
2210 * @param linePrefix prefix to put in front of each location.
2211 * @return a string describing the call stack.
2212 * {@hide}
2213 */
2214 public static String getCallers(final int depth, String linePrefix) {
2215 final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
2216 StringBuffer sb = new StringBuffer();
2217 for (int i = 0; i < depth; i++) {
2218 sb.append(linePrefix).append(getCaller(callStack, i)).append("\n");
2219 }
2220 return sb.toString();
2221 }
2222
2223 /**
Ian Rogersfe067a42013-02-22 19:59:23 -08002224 * @return a String describing the immediate caller of the calling method.
Craig Mautnera51a9562012-04-17 17:05:26 -07002225 * {@hide}
2226 */
2227 public static String getCaller() {
2228 return getCaller(Thread.currentThread().getStackTrace(), 0);
2229 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002230}