1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.os;
18 
19 
20 import android.compat.annotation.UnsupportedAppUsage;
21 
22 import java.util.ArrayList;
23 
24 /**
25  * Collects performance data between two function calls in Bundle objects and
26  * outputs the results using writer of type {@link PerformanceResultsWriter}.
27  * <p>
28  * {@link #beginSnapshot(String)} and {@link #endSnapshot()} functions collect
29  * memory usage information and measure runtime between calls to begin and end.
30  * These functions logically wrap around an entire test, and should be called
31  * with name of test as the label, e.g. EmailPerformanceTest.
32  * <p>
33  * {@link #startTiming(String)} and {@link #stopTiming(String)} functions
34  * measure runtime between calls to start and stop. These functions logically
35  * wrap around a single test case or a small block of code, and should be called
36  * with the name of test case as the label, e.g. testSimpleSendMailSequence.
37  * <p>
38  * {@link #addIteration(String)} inserts intermediate measurement point which
39  * can be labeled with a String, e.g. Launch email app, compose, send, etc.
40  * <p>
41  * Snapshot and timing functions do not interfere with each other, and thus can
42  * be called in any order. The intended structure is to wrap begin/endSnapshot
43  * around calls to start/stopTiming, for example:
44  * <p>
45  * <code>beginSnapshot("EmailPerformanceTest");
46  * startTiming("testSimpleSendSequence");
47  * addIteration("Launch email app");
48  * addIteration("Compose");
49  * stopTiming("Send");
50  * startTiming("testComplexSendSequence");
51  * stopTiming("");
52  * startTiming("testAddLabel");
53  * stopTiming("");
54  * endSnapshot();</code>
55  * <p>
56  * Structure of results output is up to implementor of
57  * {@link PerformanceResultsWriter }.
58  *
59  * {@hide} Pending approval for public API.
60  */
61 public class PerformanceCollector {
62 
63     /**
64      * Interface for reporting performance data.
65      */
66     public interface PerformanceResultsWriter {
67 
68         /**
69          * Callback invoked as first action in
70          * PerformanceCollector#beginSnapshot(String) for reporting the start of
71          * a performance snapshot.
72          *
73          * @param label description of code block between beginSnapshot and
74          *              PerformanceCollector#endSnapshot()
75          * @see PerformanceCollector#beginSnapshot(String)
76          */
writeBeginSnapshot(String label)77         public void writeBeginSnapshot(String label);
78 
79         /**
80          * Callback invoked as last action in PerformanceCollector#endSnapshot()
81          * for reporting performance data collected in the snapshot.
82          *
83          * @param results memory and runtime metrics stored as key/value pairs,
84          *        in the same structure as returned by
85          *        PerformanceCollector#endSnapshot()
86          * @see PerformanceCollector#endSnapshot()
87          */
writeEndSnapshot(Bundle results)88         public void writeEndSnapshot(Bundle results);
89 
90         /**
91          * Callback invoked as first action in
92          * PerformanceCollector#startTiming(String) for reporting the start of
93          * a timing measurement.
94          *
95          * @param label description of code block between startTiming and
96          *              PerformanceCollector#stopTiming(String)
97          * @see PerformanceCollector#startTiming(String)
98          */
writeStartTiming(String label)99         public void writeStartTiming(String label);
100 
101         /**
102          * Callback invoked as last action in
103          * {@link PerformanceCollector#stopTiming(String)} for reporting the
104          * sequence of timings measured.
105          *
106          * @param results runtime metrics of code block between calls to
107          *                startTiming and stopTiming, in the same structure as
108          *                returned by PerformanceCollector#stopTiming(String)
109          * @see PerformanceCollector#stopTiming(String)
110          */
writeStopTiming(Bundle results)111         public void writeStopTiming(Bundle results);
112 
113         /**
114          * Callback invoked as last action in
115          * {@link PerformanceCollector#addMeasurement(String, long)} for
116          * reporting an integer type measurement.
117          *
118          * @param label short description of the metric that was measured
119          * @param value long value of the measurement
120          */
writeMeasurement(String label, long value)121         public void writeMeasurement(String label, long value);
122 
123         /**
124          * Callback invoked as last action in
125          * {@link PerformanceCollector#addMeasurement(String, float)} for
126          * reporting a float type measurement.
127          *
128          * @param label short description of the metric that was measured
129          * @param value float value of the measurement
130          */
writeMeasurement(String label, float value)131         public void writeMeasurement(String label, float value);
132 
133         /**
134          * Callback invoked as last action in
135          * {@link PerformanceCollector#addMeasurement(String, String)} for
136          * reporting a string field.
137          *
138          * @param label short description of the metric that was measured
139          * @param value string summary of the measurement
140          */
writeMeasurement(String label, String value)141         public void writeMeasurement(String label, String value);
142     }
143 
144     /**
145      * In a results Bundle, this key references a List of iteration Bundles.
146      */
147     public static final String METRIC_KEY_ITERATIONS = "iterations";
148     /**
149      * In an iteration Bundle, this key describes the iteration.
150      */
151     public static final String METRIC_KEY_LABEL = "label";
152     /**
153      * In a results Bundle, this key reports the cpu time of the code block
154      * under measurement.
155      */
156     public static final String METRIC_KEY_CPU_TIME = "cpu_time";
157     /**
158      * In a results Bundle, this key reports the execution time of the code
159      * block under measurement.
160      */
161     public static final String METRIC_KEY_EXECUTION_TIME = "execution_time";
162     /**
163      * In a snapshot Bundle, this key reports the number of received
164      * transactions from the binder driver before collection started.
165      */
166     public static final String METRIC_KEY_PRE_RECEIVED_TRANSACTIONS = "pre_received_transactions";
167     /**
168      * In a snapshot Bundle, this key reports the number of transactions sent by
169      * the running program before collection started.
170      */
171     public static final String METRIC_KEY_PRE_SENT_TRANSACTIONS = "pre_sent_transactions";
172     /**
173      * In a snapshot Bundle, this key reports the number of received
174      * transactions from the binder driver.
175      */
176     public static final String METRIC_KEY_RECEIVED_TRANSACTIONS = "received_transactions";
177     /**
178      * In a snapshot Bundle, this key reports the number of transactions sent by
179      * the running program.
180      */
181     public static final String METRIC_KEY_SENT_TRANSACTIONS = "sent_transactions";
182     /**
183      * In a snapshot Bundle, this key reports the number of garbage collection
184      * invocations.
185      */
186     public static final String METRIC_KEY_GC_INVOCATION_COUNT = "gc_invocation_count";
187     /**
188      * In a snapshot Bundle, this key reports the amount of allocated memory
189      * used by the running program.
190      */
191     public static final String METRIC_KEY_JAVA_ALLOCATED = "java_allocated";
192     /**
193      * In a snapshot Bundle, this key reports the amount of free memory
194      * available to the running program.
195      */
196     public static final String METRIC_KEY_JAVA_FREE = "java_free";
197     /**
198      * In a snapshot Bundle, this key reports the number of private dirty pages
199      * used by dalvik.
200      */
201     public static final String METRIC_KEY_JAVA_PRIVATE_DIRTY = "java_private_dirty";
202     /**
203      * In a snapshot Bundle, this key reports the proportional set size for
204      * dalvik.
205      */
206     public static final String METRIC_KEY_JAVA_PSS = "java_pss";
207     /**
208      * In a snapshot Bundle, this key reports the number of shared dirty pages
209      * used by dalvik.
210      */
211     public static final String METRIC_KEY_JAVA_SHARED_DIRTY = "java_shared_dirty";
212     /**
213      * In a snapshot Bundle, this key reports the total amount of memory
214      * available to the running program.
215      */
216     public static final String METRIC_KEY_JAVA_SIZE = "java_size";
217     /**
218      * In a snapshot Bundle, this key reports the amount of allocated memory in
219      * the native heap.
220      */
221     public static final String METRIC_KEY_NATIVE_ALLOCATED = "native_allocated";
222     /**
223      * In a snapshot Bundle, this key reports the amount of free memory in the
224      * native heap.
225      */
226     public static final String METRIC_KEY_NATIVE_FREE = "native_free";
227     /**
228      * In a snapshot Bundle, this key reports the number of private dirty pages
229      * used by the native heap.
230      */
231     public static final String METRIC_KEY_NATIVE_PRIVATE_DIRTY = "native_private_dirty";
232     /**
233      * In a snapshot Bundle, this key reports the proportional set size for the
234      * native heap.
235      */
236     public static final String METRIC_KEY_NATIVE_PSS = "native_pss";
237     /**
238      * In a snapshot Bundle, this key reports the number of shared dirty pages
239      * used by the native heap.
240      */
241     public static final String METRIC_KEY_NATIVE_SHARED_DIRTY = "native_shared_dirty";
242     /**
243      * In a snapshot Bundle, this key reports the size of the native heap.
244      */
245     public static final String METRIC_KEY_NATIVE_SIZE = "native_size";
246     /**
247      * In a snapshot Bundle, this key reports the number of objects allocated
248      * globally.
249      */
250     public static final String METRIC_KEY_GLOBAL_ALLOC_COUNT = "global_alloc_count";
251     /**
252      * In a snapshot Bundle, this key reports the size of all objects allocated
253      * globally.
254      */
255     public static final String METRIC_KEY_GLOBAL_ALLOC_SIZE = "global_alloc_size";
256     /**
257      * In a snapshot Bundle, this key reports the number of objects freed
258      * globally.
259      */
260     public static final String METRIC_KEY_GLOBAL_FREED_COUNT = "global_freed_count";
261     /**
262      * In a snapshot Bundle, this key reports the size of all objects freed
263      * globally.
264      */
265     public static final String METRIC_KEY_GLOBAL_FREED_SIZE = "global_freed_size";
266     /**
267      * In a snapshot Bundle, this key reports the number of private dirty pages
268      * used by everything else.
269      */
270     public static final String METRIC_KEY_OTHER_PRIVATE_DIRTY = "other_private_dirty";
271     /**
272      * In a snapshot Bundle, this key reports the proportional set size for
273      * everything else.
274      */
275     public static final String METRIC_KEY_OTHER_PSS = "other_pss";
276     /**
277      * In a snapshot Bundle, this key reports the number of shared dirty pages
278      * used by everything else.
279      */
280     public static final String METRIC_KEY_OTHER_SHARED_DIRTY = "other_shared_dirty";
281 
282     private PerformanceResultsWriter mPerfWriter;
283     private Bundle mPerfSnapshot;
284     private Bundle mPerfMeasurement;
285     private long mSnapshotCpuTime;
286     private long mSnapshotExecTime;
287     private long mCpuTime;
288     private long mExecTime;
289 
290     @UnsupportedAppUsage
PerformanceCollector()291     public PerformanceCollector() {
292     }
293 
PerformanceCollector(PerformanceResultsWriter writer)294     public PerformanceCollector(PerformanceResultsWriter writer) {
295         setPerformanceResultsWriter(writer);
296     }
297 
setPerformanceResultsWriter(PerformanceResultsWriter writer)298     public void setPerformanceResultsWriter(PerformanceResultsWriter writer) {
299         mPerfWriter = writer;
300     }
301 
302     /**
303      * Begin collection of memory usage information.
304      *
305      * @param label description of code block between beginSnapshot and
306      *              endSnapshot, used to label output
307      */
308     @UnsupportedAppUsage
beginSnapshot(String label)309     public void beginSnapshot(String label) {
310         if (mPerfWriter != null)
311             mPerfWriter.writeBeginSnapshot(label);
312         startPerformanceSnapshot();
313     }
314 
315     /**
316      * End collection of memory usage information. Returns collected data in a
317      * Bundle object.
318      *
319      * @return Memory and runtime metrics stored as key/value pairs. Values are
320      *         of type long, and keys include:
321      *         <ul>
322      *         <li>{@link #METRIC_KEY_CPU_TIME cpu_time}
323      *         <li>{@link #METRIC_KEY_EXECUTION_TIME execution_time}
324      *         <li>{@link #METRIC_KEY_PRE_RECEIVED_TRANSACTIONS
325      *         pre_received_transactions}
326      *         <li>{@link #METRIC_KEY_PRE_SENT_TRANSACTIONS
327      *         pre_sent_transactions}
328      *         <li>{@link #METRIC_KEY_RECEIVED_TRANSACTIONS
329      *         received_transactions}
330      *         <li>{@link #METRIC_KEY_SENT_TRANSACTIONS sent_transactions}
331      *         <li>{@link #METRIC_KEY_GC_INVOCATION_COUNT gc_invocation_count}
332      *         <li>{@link #METRIC_KEY_JAVA_ALLOCATED java_allocated}
333      *         <li>{@link #METRIC_KEY_JAVA_FREE java_free}
334      *         <li>{@link #METRIC_KEY_JAVA_PRIVATE_DIRTY java_private_dirty}
335      *         <li>{@link #METRIC_KEY_JAVA_PSS java_pss}
336      *         <li>{@link #METRIC_KEY_JAVA_SHARED_DIRTY java_shared_dirty}
337      *         <li>{@link #METRIC_KEY_JAVA_SIZE java_size}
338      *         <li>{@link #METRIC_KEY_NATIVE_ALLOCATED native_allocated}
339      *         <li>{@link #METRIC_KEY_NATIVE_FREE native_free}
340      *         <li>{@link #METRIC_KEY_NATIVE_PRIVATE_DIRTY native_private_dirty}
341      *         <li>{@link #METRIC_KEY_NATIVE_PSS native_pss}
342      *         <li>{@link #METRIC_KEY_NATIVE_SHARED_DIRTY native_shared_dirty}
343      *         <li>{@link #METRIC_KEY_NATIVE_SIZE native_size}
344      *         <li>{@link #METRIC_KEY_GLOBAL_ALLOC_COUNT global_alloc_count}
345      *         <li>{@link #METRIC_KEY_GLOBAL_ALLOC_SIZE global_alloc_size}
346      *         <li>{@link #METRIC_KEY_GLOBAL_FREED_COUNT global_freed_count}
347      *         <li>{@link #METRIC_KEY_GLOBAL_FREED_SIZE global_freed_size}
348      *         <li>{@link #METRIC_KEY_OTHER_PRIVATE_DIRTY other_private_dirty}
349      *         <li>{@link #METRIC_KEY_OTHER_PSS other_pss}
350      *         <li>{@link #METRIC_KEY_OTHER_SHARED_DIRTY other_shared_dirty}
351      *         </ul>
352      */
353     @UnsupportedAppUsage
endSnapshot()354     public Bundle endSnapshot() {
355         endPerformanceSnapshot();
356         if (mPerfWriter != null)
357             mPerfWriter.writeEndSnapshot(mPerfSnapshot);
358         return mPerfSnapshot;
359     }
360 
361     /**
362      * Start measurement of user and cpu time.
363      *
364      * @param label description of code block between startTiming and
365      *        stopTiming, used to label output
366      */
367     @UnsupportedAppUsage
startTiming(String label)368     public void startTiming(String label) {
369         if (mPerfWriter != null)
370             mPerfWriter.writeStartTiming(label);
371         mPerfMeasurement = new Bundle();
372         mPerfMeasurement.putParcelableArrayList(
373                 METRIC_KEY_ITERATIONS, new ArrayList<Parcelable>());
374         mExecTime = SystemClock.uptimeMillis();
375         mCpuTime = Process.getElapsedCpuTime();
376     }
377 
378     /**
379      * Add a measured segment, and start measuring the next segment. Returns
380      * collected data in a Bundle object.
381      *
382      * @param label description of code block between startTiming and
383      *              addIteration, and between two calls to addIteration, used
384      *              to label output
385      * @return Runtime metrics stored as key/value pairs. Values are of type
386      *         long, and keys include:
387      *         <ul>
388      *         <li>{@link #METRIC_KEY_LABEL label}
389      *         <li>{@link #METRIC_KEY_CPU_TIME cpu_time}
390      *         <li>{@link #METRIC_KEY_EXECUTION_TIME execution_time}
391      *         </ul>
392      */
addIteration(String label)393     public Bundle addIteration(String label) {
394         mCpuTime = Process.getElapsedCpuTime() - mCpuTime;
395         mExecTime = SystemClock.uptimeMillis() - mExecTime;
396 
397         Bundle iteration = new Bundle();
398         iteration.putString(METRIC_KEY_LABEL, label);
399         iteration.putLong(METRIC_KEY_EXECUTION_TIME, mExecTime);
400         iteration.putLong(METRIC_KEY_CPU_TIME, mCpuTime);
401         mPerfMeasurement.getParcelableArrayList(METRIC_KEY_ITERATIONS).add(iteration);
402 
403         mExecTime = SystemClock.uptimeMillis();
404         mCpuTime = Process.getElapsedCpuTime();
405         return iteration;
406     }
407 
408     /**
409      * Stop measurement of user and cpu time.
410      *
411      * @param label description of code block between addIteration or
412      *              startTiming and stopTiming, used to label output
413      * @return Runtime metrics stored in a bundle, including all iterations
414      *         between calls to startTiming and stopTiming. List of iterations
415      *         is keyed by {@link #METRIC_KEY_ITERATIONS iterations}.
416      */
417     @UnsupportedAppUsage
stopTiming(String label)418     public Bundle stopTiming(String label) {
419         addIteration(label);
420         if (mPerfWriter != null)
421             mPerfWriter.writeStopTiming(mPerfMeasurement);
422         return mPerfMeasurement;
423     }
424 
425     /**
426      * Add an integer type measurement to the collector.
427      *
428      * @param label short description of the metric that was measured
429      * @param value long value of the measurement
430      */
addMeasurement(String label, long value)431     public void addMeasurement(String label, long value) {
432         if (mPerfWriter != null)
433             mPerfWriter.writeMeasurement(label, value);
434     }
435 
436     /**
437      * Add a float type measurement to the collector.
438      *
439      * @param label short description of the metric that was measured
440      * @param value float value of the measurement
441      */
addMeasurement(String label, float value)442     public void addMeasurement(String label, float value) {
443         if (mPerfWriter != null)
444             mPerfWriter.writeMeasurement(label, value);
445     }
446 
447     /**
448      * Add a string field to the collector.
449      *
450      * @param label short description of the metric that was measured
451      * @param value string summary of the measurement
452      */
addMeasurement(String label, String value)453     public void addMeasurement(String label, String value) {
454         if (mPerfWriter != null)
455             mPerfWriter.writeMeasurement(label, value);
456     }
457 
458     /*
459      * Starts tracking memory usage, binder transactions, and real & cpu timing.
460      */
startPerformanceSnapshot()461     private void startPerformanceSnapshot() {
462         // Create new snapshot
463         mPerfSnapshot = new Bundle();
464 
465         // Add initial binder counts
466         Bundle binderCounts = getBinderCounts();
467         for (String key : binderCounts.keySet()) {
468             mPerfSnapshot.putLong("pre_" + key, binderCounts.getLong(key));
469         }
470 
471         // Force a GC and zero out the performance counters. Do this
472         // before reading initial CPU/wall-clock times so we don't include
473         // the cost of this setup in our final metrics.
474         startAllocCounting();
475 
476         // Record CPU time up to this point, and start timing. Note: this
477         // must happen at the end of this method, otherwise the timing will
478         // include noise.
479         mSnapshotExecTime = SystemClock.uptimeMillis();
480         mSnapshotCpuTime = Process.getElapsedCpuTime();
481     }
482 
483     /*
484      * Stops tracking memory usage, binder transactions, and real & cpu timing.
485      * Stores collected data as type long into Bundle object for reporting.
486      */
endPerformanceSnapshot()487     private void endPerformanceSnapshot() {
488         // Stop the timing. This must be done first before any other counting is
489         // stopped.
490         mSnapshotCpuTime = Process.getElapsedCpuTime() - mSnapshotCpuTime;
491         mSnapshotExecTime = SystemClock.uptimeMillis() - mSnapshotExecTime;
492 
493         stopAllocCounting();
494 
495         long nativeMax = Debug.getNativeHeapSize() / 1024;
496         long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
497         long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
498 
499         Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
500         Debug.getMemoryInfo(memInfo);
501 
502         Runtime runtime = Runtime.getRuntime();
503 
504         long dalvikMax = runtime.totalMemory() / 1024;
505         long dalvikFree = runtime.freeMemory() / 1024;
506         long dalvikAllocated = dalvikMax - dalvikFree;
507 
508         // Add final binder counts
509         Bundle binderCounts = getBinderCounts();
510         for (String key : binderCounts.keySet()) {
511             mPerfSnapshot.putLong(key, binderCounts.getLong(key));
512         }
513 
514         // Add alloc counts
515         Bundle allocCounts = getAllocCounts();
516         for (String key : allocCounts.keySet()) {
517             mPerfSnapshot.putLong(key, allocCounts.getLong(key));
518         }
519 
520         mPerfSnapshot.putLong(METRIC_KEY_EXECUTION_TIME, mSnapshotExecTime);
521         mPerfSnapshot.putLong(METRIC_KEY_CPU_TIME, mSnapshotCpuTime);
522 
523         mPerfSnapshot.putLong(METRIC_KEY_NATIVE_SIZE, nativeMax);
524         mPerfSnapshot.putLong(METRIC_KEY_NATIVE_ALLOCATED, nativeAllocated);
525         mPerfSnapshot.putLong(METRIC_KEY_NATIVE_FREE, nativeFree);
526         mPerfSnapshot.putLong(METRIC_KEY_NATIVE_PSS, memInfo.nativePss);
527         mPerfSnapshot.putLong(METRIC_KEY_NATIVE_PRIVATE_DIRTY, memInfo.nativePrivateDirty);
528         mPerfSnapshot.putLong(METRIC_KEY_NATIVE_SHARED_DIRTY, memInfo.nativeSharedDirty);
529 
530         mPerfSnapshot.putLong(METRIC_KEY_JAVA_SIZE, dalvikMax);
531         mPerfSnapshot.putLong(METRIC_KEY_JAVA_ALLOCATED, dalvikAllocated);
532         mPerfSnapshot.putLong(METRIC_KEY_JAVA_FREE, dalvikFree);
533         mPerfSnapshot.putLong(METRIC_KEY_JAVA_PSS, memInfo.dalvikPss);
534         mPerfSnapshot.putLong(METRIC_KEY_JAVA_PRIVATE_DIRTY, memInfo.dalvikPrivateDirty);
535         mPerfSnapshot.putLong(METRIC_KEY_JAVA_SHARED_DIRTY, memInfo.dalvikSharedDirty);
536 
537         mPerfSnapshot.putLong(METRIC_KEY_OTHER_PSS, memInfo.otherPss);
538         mPerfSnapshot.putLong(METRIC_KEY_OTHER_PRIVATE_DIRTY, memInfo.otherPrivateDirty);
539         mPerfSnapshot.putLong(METRIC_KEY_OTHER_SHARED_DIRTY, memInfo.otherSharedDirty);
540     }
541 
542     /*
543      * Starts allocation counting. This triggers a gc and resets the counts.
544      */
startAllocCounting()545     private static void startAllocCounting() {
546         // Before we start trigger a GC and reset the debug counts. Run the
547         // finalizers and another GC before starting and stopping the alloc
548         // counts. This will free up any objects that were just sitting around
549         // waiting for their finalizers to be run.
550         Runtime.getRuntime().gc();
551         Runtime.getRuntime().runFinalization();
552         Runtime.getRuntime().gc();
553 
554         Debug.resetAllCounts();
555 
556         // start the counts
557         Debug.startAllocCounting();
558     }
559 
560     /*
561      * Stops allocation counting.
562      */
stopAllocCounting()563     private static void stopAllocCounting() {
564         Runtime.getRuntime().gc();
565         Runtime.getRuntime().runFinalization();
566         Runtime.getRuntime().gc();
567         Debug.stopAllocCounting();
568     }
569 
570     /*
571      * Returns a bundle with the current results from the allocation counting.
572      */
getAllocCounts()573     private static Bundle getAllocCounts() {
574         Bundle results = new Bundle();
575         results.putLong(METRIC_KEY_GLOBAL_ALLOC_COUNT, Debug.getGlobalAllocCount());
576         results.putLong(METRIC_KEY_GLOBAL_ALLOC_SIZE, Debug.getGlobalAllocSize());
577         results.putLong(METRIC_KEY_GLOBAL_FREED_COUNT, Debug.getGlobalFreedCount());
578         results.putLong(METRIC_KEY_GLOBAL_FREED_SIZE, Debug.getGlobalFreedSize());
579         results.putLong(METRIC_KEY_GC_INVOCATION_COUNT, Debug.getGlobalGcInvocationCount());
580         return results;
581     }
582 
583     /*
584      * Returns a bundle with the counts for various binder counts for this
585      * process. Currently the only two that are reported are the number of send
586      * and the number of received transactions.
587      */
getBinderCounts()588     private static Bundle getBinderCounts() {
589         Bundle results = new Bundle();
590         results.putLong(METRIC_KEY_SENT_TRANSACTIONS, Debug.getBinderSentTransactions());
591         results.putLong(METRIC_KEY_RECEIVED_TRANSACTIONS, Debug.getBinderReceivedTransactions());
592         return results;
593     }
594 }
595