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