Merge commit '65e301c09bf88a0a390b0a5924b2844804b9ce5b' * commit '65e301c09bf88a0a390b0a5924b2844804b9ce5b': Performance measurement framework:
This commit is contained in:
@@ -24,6 +24,7 @@ import android.content.IntentFilter;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.os.PerformanceCollector;
|
||||
import android.os.RemoteException;
|
||||
import android.os.Debug;
|
||||
import android.os.IBinder;
|
||||
@@ -83,10 +84,8 @@ public class Instrumentation {
|
||||
private List<ActivityWaiter> mWaitingActivities;
|
||||
private List<ActivityMonitor> mActivityMonitors;
|
||||
private IInstrumentationWatcher mWatcher;
|
||||
private long mPreCpuTime;
|
||||
private long mStart;
|
||||
private boolean mAutomaticPerformanceSnapshots = false;
|
||||
private Bundle mPrePerfMetrics = new Bundle();
|
||||
private PerformanceCollector mPerformanceCollector;
|
||||
private Bundle mPerfMetrics = new Bundle();
|
||||
|
||||
public Instrumentation() {
|
||||
@@ -191,96 +190,21 @@ public class Instrumentation {
|
||||
|
||||
public void setAutomaticPerformanceSnapshots() {
|
||||
mAutomaticPerformanceSnapshots = true;
|
||||
mPerformanceCollector = new PerformanceCollector();
|
||||
}
|
||||
|
||||
public void startPerformanceSnapshot() {
|
||||
mStart = 0;
|
||||
if (!isProfiling()) {
|
||||
// Add initial binder counts
|
||||
Bundle binderCounts = getBinderCounts();
|
||||
for (String key: binderCounts.keySet()) {
|
||||
addPerfMetricLong("pre_" + key, binderCounts.getLong(key));
|
||||
}
|
||||
|
||||
// Force a GC and zero out the performance counters. Do this
|
||||
// before reading initial CPU/wall-clock times so we don't include
|
||||
// the cost of this setup in our final metrics.
|
||||
startAllocCounting();
|
||||
|
||||
// Record CPU time up to this point, and start timing. Note: this
|
||||
// must happen at the end of this method, otherwise the timing will
|
||||
// include noise.
|
||||
mStart = SystemClock.uptimeMillis();
|
||||
mPreCpuTime = Process.getElapsedCpuTime();
|
||||
mPerformanceCollector.beginSnapshot(null);
|
||||
}
|
||||
}
|
||||
|
||||
public void endPerformanceSnapshot() {
|
||||
if (!isProfiling()) {
|
||||
// Stop the timing. This must be done first before any other counting is stopped.
|
||||
long cpuTime = Process.getElapsedCpuTime();
|
||||
long duration = SystemClock.uptimeMillis();
|
||||
|
||||
stopAllocCounting();
|
||||
|
||||
long nativeMax = Debug.getNativeHeapSize() / 1024;
|
||||
long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
|
||||
long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
|
||||
|
||||
Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
|
||||
Debug.getMemoryInfo(memInfo);
|
||||
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
|
||||
long dalvikMax = runtime.totalMemory() / 1024;
|
||||
long dalvikFree = runtime.freeMemory() / 1024;
|
||||
long dalvikAllocated = dalvikMax - dalvikFree;
|
||||
|
||||
// Add final binder counts
|
||||
Bundle binderCounts = getBinderCounts();
|
||||
for (String key: binderCounts.keySet()) {
|
||||
addPerfMetricLong(key, binderCounts.getLong(key));
|
||||
}
|
||||
|
||||
// Add alloc counts
|
||||
Bundle allocCounts = getAllocCounts();
|
||||
for (String key: allocCounts.keySet()) {
|
||||
addPerfMetricLong(key, allocCounts.getLong(key));
|
||||
}
|
||||
|
||||
addPerfMetricLong("execution_time", duration - mStart);
|
||||
addPerfMetricLong("pre_cpu_time", mPreCpuTime);
|
||||
addPerfMetricLong("cpu_time", cpuTime - mPreCpuTime);
|
||||
|
||||
addPerfMetricLong("native_size", nativeMax);
|
||||
addPerfMetricLong("native_allocated", nativeAllocated);
|
||||
addPerfMetricLong("native_free", nativeFree);
|
||||
addPerfMetricInt("native_pss", memInfo.nativePss);
|
||||
addPerfMetricInt("native_private_dirty", memInfo.nativePrivateDirty);
|
||||
addPerfMetricInt("native_shared_dirty", memInfo.nativeSharedDirty);
|
||||
|
||||
addPerfMetricLong("java_size", dalvikMax);
|
||||
addPerfMetricLong("java_allocated", dalvikAllocated);
|
||||
addPerfMetricLong("java_free", dalvikFree);
|
||||
addPerfMetricInt("java_pss", memInfo.dalvikPss);
|
||||
addPerfMetricInt("java_private_dirty", memInfo.dalvikPrivateDirty);
|
||||
addPerfMetricInt("java_shared_dirty", memInfo.dalvikSharedDirty);
|
||||
|
||||
addPerfMetricInt("other_pss", memInfo.otherPss);
|
||||
addPerfMetricInt("other_private_dirty", memInfo.otherPrivateDirty);
|
||||
addPerfMetricInt("other_shared_dirty", memInfo.otherSharedDirty);
|
||||
|
||||
mPerfMetrics = mPerformanceCollector.endSnapshot();
|
||||
}
|
||||
}
|
||||
|
||||
private void addPerfMetricLong(String key, long value) {
|
||||
mPerfMetrics.putLong("performance." + key, value);
|
||||
}
|
||||
|
||||
private void addPerfMetricInt(String key, int value) {
|
||||
mPerfMetrics.putInt("performance." + key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the instrumented application is stopping, after all of the
|
||||
* normal application cleanup has occurred.
|
||||
|
||||
524
core/java/android/os/PerformanceCollector.java
Normal file
524
core/java/android/os/PerformanceCollector.java
Normal file
@@ -0,0 +1,524 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.os;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Collects performance data between two function calls in Bundle objects and
|
||||
* outputs the results using writer of type {@link PerformanceResultsWriter}.
|
||||
* <p>
|
||||
* {@link #beginSnapshot(String)} and {@link #endSnapshot()} functions collect
|
||||
* memory usage information and measure runtime between calls to begin and end.
|
||||
* These functions logically wrap around an entire test, and should be called
|
||||
* with name of test as the label, e.g. EmailPerformanceTest.
|
||||
* <p>
|
||||
* {@link #startTiming(String)} and {@link #stopTiming(String)} functions
|
||||
* measure runtime between calls to start and stop. These functions logically
|
||||
* wrap around a single test case or a small block of code, and should be called
|
||||
* with the name of test case as the label, e.g. testSimpleSendMailSequence.
|
||||
* <p>
|
||||
* {@link #addIteration(String)} inserts intermediate measurement point which
|
||||
* can be labeled with a String, e.g. Launch email app, compose, send, etc.
|
||||
* <p>
|
||||
* Snapshot and timing functions do not interfere with each other, and thus can
|
||||
* be called in any order. The intended structure is to wrap begin/endSnapshot
|
||||
* around calls to start/stopTiming, for example:
|
||||
* <p>
|
||||
* <code>beginSnapshot("EmailPerformanceTest");
|
||||
* startTiming("testSimpleSendSequence");
|
||||
* addIteration("Launch email app");
|
||||
* addIteration("Compose");
|
||||
* stopTiming("Send");
|
||||
* startTiming("testComplexSendSequence");
|
||||
* stopTiming("");
|
||||
* startTiming("testAddLabel");
|
||||
* stopTiming("");
|
||||
* endSnapshot();</code>
|
||||
* <p>
|
||||
* Structure of results output is up to implementor of
|
||||
* {@link PerformanceResultsWriter }.
|
||||
*
|
||||
* {@hide} Pending approval for public API.
|
||||
*/
|
||||
public class PerformanceCollector {
|
||||
|
||||
/**
|
||||
* Interface for reporting performance data.
|
||||
*/
|
||||
public interface PerformanceResultsWriter {
|
||||
|
||||
/**
|
||||
* Callback invoked as first action in
|
||||
* PerformanceCollector#beginSnapshot(String) for reporting the start of
|
||||
* a performance snapshot.
|
||||
*
|
||||
* @param label description of code block between beginSnapshot and
|
||||
* PerformanceCollector#endSnapshot()
|
||||
* @see PerformanceCollector#beginSnapshot(String)
|
||||
*/
|
||||
public void writeBeginSnapshot(String label);
|
||||
|
||||
/**
|
||||
* Callback invoked as last action in PerformanceCollector#endSnapshot()
|
||||
* for reporting performance data collected in the snapshot.
|
||||
*
|
||||
* @param results memory and runtime metrics stored as key/value pairs,
|
||||
* in the same structure as returned by
|
||||
* PerformanceCollector#endSnapshot()
|
||||
* @see PerformanceCollector#endSnapshot()
|
||||
*/
|
||||
public void writeEndSnapshot(Bundle results);
|
||||
|
||||
/**
|
||||
* Callback invoked as first action in
|
||||
* PerformanceCollector#startTiming(String) for reporting the start of
|
||||
* a timing measurement.
|
||||
*
|
||||
* @param label description of code block between startTiming and
|
||||
* PerformanceCollector#stopTiming(String)
|
||||
* @see PerformanceCollector#startTiming(String)
|
||||
*/
|
||||
public void writeStartTiming(String label);
|
||||
|
||||
/**
|
||||
* Callback invoked as last action in
|
||||
* {@link PerformanceCollector#stopTiming(String)} for reporting the
|
||||
* sequence of timings measured.
|
||||
*
|
||||
* @param results runtime metrics of code block between calls to
|
||||
* startTiming and stopTiming, in the same structure as
|
||||
* returned by PerformanceCollector#stopTiming(String)
|
||||
* @see PerformanceCollector#stopTiming(String)
|
||||
*/
|
||||
public void writeStopTiming(Bundle results);
|
||||
}
|
||||
|
||||
/**
|
||||
* In a results Bundle, this key references a List of iteration Bundles.
|
||||
*/
|
||||
public static final String METRIC_KEY_ITERATIONS = "iterations";
|
||||
/**
|
||||
* In an iteration Bundle, this key describes the iteration.
|
||||
*/
|
||||
public static final String METRIC_KEY_LABEL = "label";
|
||||
/**
|
||||
* In a results Bundle, this key reports the cpu time of the code block
|
||||
* under measurement.
|
||||
*/
|
||||
public static final String METRIC_KEY_CPU_TIME = "cpu_time";
|
||||
/**
|
||||
* In a results Bundle, this key reports the execution time of the code
|
||||
* block under measurement.
|
||||
*/
|
||||
public static final String METRIC_KEY_EXECUTION_TIME = "execution_time";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the number of received
|
||||
* transactions from the binder driver before collection started.
|
||||
*/
|
||||
public static final String METRIC_KEY_PRE_RECEIVED_TRANSACTIONS = "pre_received_transactions";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the number of transactions sent by
|
||||
* the running program before collection started.
|
||||
*/
|
||||
public static final String METRIC_KEY_PRE_SENT_TRANSACTIONS = "pre_sent_transactions";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the number of received
|
||||
* transactions from the binder driver.
|
||||
*/
|
||||
public static final String METRIC_KEY_RECEIVED_TRANSACTIONS = "received_transactions";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the number of transactions sent by
|
||||
* the running program.
|
||||
*/
|
||||
public static final String METRIC_KEY_SENT_TRANSACTIONS = "sent_transactions";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the number of garbage collection
|
||||
* invocations.
|
||||
*/
|
||||
public static final String METRIC_KEY_GC_INVOCATION_COUNT = "gc_invocation_count";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the amount of allocated memory
|
||||
* used by the running program.
|
||||
*/
|
||||
public static final String METRIC_KEY_JAVA_ALLOCATED = "java_allocated";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the amount of free memory
|
||||
* available to the running program.
|
||||
*/
|
||||
public static final String METRIC_KEY_JAVA_FREE = "java_free";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the number of private dirty pages
|
||||
* used by dalvik.
|
||||
*/
|
||||
public static final String METRIC_KEY_JAVA_PRIVATE_DIRTY = "java_private_dirty";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the proportional set size for
|
||||
* dalvik.
|
||||
*/
|
||||
public static final String METRIC_KEY_JAVA_PSS = "java_pss";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the number of shared dirty pages
|
||||
* used by dalvik.
|
||||
*/
|
||||
public static final String METRIC_KEY_JAVA_SHARED_DIRTY = "java_shared_dirty";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the total amount of memory
|
||||
* available to the running program.
|
||||
*/
|
||||
public static final String METRIC_KEY_JAVA_SIZE = "java_size";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the amount of allocated memory in
|
||||
* the native heap.
|
||||
*/
|
||||
public static final String METRIC_KEY_NATIVE_ALLOCATED = "native_allocated";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the amount of free memory in the
|
||||
* native heap.
|
||||
*/
|
||||
public static final String METRIC_KEY_NATIVE_FREE = "native_free";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the number of private dirty pages
|
||||
* used by the native heap.
|
||||
*/
|
||||
public static final String METRIC_KEY_NATIVE_PRIVATE_DIRTY = "native_private_dirty";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the proportional set size for the
|
||||
* native heap.
|
||||
*/
|
||||
public static final String METRIC_KEY_NATIVE_PSS = "native_pss";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the number of shared dirty pages
|
||||
* used by the native heap.
|
||||
*/
|
||||
public static final String METRIC_KEY_NATIVE_SHARED_DIRTY = "native_shared_dirty";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the size of the native heap.
|
||||
*/
|
||||
public static final String METRIC_KEY_NATIVE_SIZE = "native_size";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the number of objects allocated
|
||||
* globally.
|
||||
*/
|
||||
public static final String METRIC_KEY_GLOBAL_ALLOC_COUNT = "global_alloc_count";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the size of all objects allocated
|
||||
* globally.
|
||||
*/
|
||||
public static final String METRIC_KEY_GLOBAL_ALLOC_SIZE = "global_alloc_size";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the number of objects freed
|
||||
* globally.
|
||||
*/
|
||||
public static final String METRIC_KEY_GLOBAL_FREED_COUNT = "global_freed_count";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the size of all objects freed
|
||||
* globally.
|
||||
*/
|
||||
public static final String METRIC_KEY_GLOBAL_FREED_SIZE = "global_freed_size";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the number of private dirty pages
|
||||
* used by everything else.
|
||||
*/
|
||||
public static final String METRIC_KEY_OTHER_PRIVATE_DIRTY = "other_private_dirty";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the proportional set size for
|
||||
* everything else.
|
||||
*/
|
||||
public static final String METRIC_KEY_OTHER_PSS = "other_pss";
|
||||
/**
|
||||
* In a snapshot Bundle, this key reports the number of shared dirty pages
|
||||
* used by everything else.
|
||||
*/
|
||||
public static final String METRIC_KEY_OTHER_SHARED_DIRTY = "other_shared_dirty";
|
||||
|
||||
private PerformanceResultsWriter mPerfWriter;
|
||||
private Bundle mPerfSnapshot;
|
||||
private Bundle mPerfMeasurement;
|
||||
private long mSnapshotCpuTime;
|
||||
private long mSnapshotExecTime;
|
||||
private long mCpuTime;
|
||||
private long mExecTime;
|
||||
|
||||
public PerformanceCollector() {
|
||||
}
|
||||
|
||||
public PerformanceCollector(PerformanceResultsWriter writer) {
|
||||
setPerformanceResultsWriter(writer);
|
||||
}
|
||||
|
||||
public void setPerformanceResultsWriter(PerformanceResultsWriter writer) {
|
||||
mPerfWriter = writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin collection of memory usage information.
|
||||
*
|
||||
* @param label description of code block between beginSnapshot and
|
||||
* endSnapshot, used to label output
|
||||
*/
|
||||
public void beginSnapshot(String label) {
|
||||
if (mPerfWriter != null)
|
||||
mPerfWriter.writeBeginSnapshot(label);
|
||||
startPerformanceSnapshot();
|
||||
}
|
||||
|
||||
/**
|
||||
* End collection of memory usage information. Returns collected data in a
|
||||
* Bundle object.
|
||||
*
|
||||
* @return Memory and runtime metrics stored as key/value pairs. Values are
|
||||
* of type long, and keys include:
|
||||
* <ul>
|
||||
* <li>{@link #METRIC_KEY_CPU_TIME cpu_time}
|
||||
* <li>{@link #METRIC_KEY_EXECUTION_TIME execution_time}
|
||||
* <li>{@link #METRIC_KEY_PRE_RECEIVED_TRANSACTIONS
|
||||
* pre_received_transactions}
|
||||
* <li>{@link #METRIC_KEY_PRE_SENT_TRANSACTIONS
|
||||
* pre_sent_transactions}
|
||||
* <li>{@link #METRIC_KEY_RECEIVED_TRANSACTIONS
|
||||
* received_transactions}
|
||||
* <li>{@link #METRIC_KEY_SENT_TRANSACTIONS sent_transactions}
|
||||
* <li>{@link #METRIC_KEY_GC_INVOCATION_COUNT gc_invocation_count}
|
||||
* <li>{@link #METRIC_KEY_JAVA_ALLOCATED java_allocated}
|
||||
* <li>{@link #METRIC_KEY_JAVA_FREE java_free}
|
||||
* <li>{@link #METRIC_KEY_JAVA_PRIVATE_DIRTY java_private_dirty}
|
||||
* <li>{@link #METRIC_KEY_JAVA_PSS java_pss}
|
||||
* <li>{@link #METRIC_KEY_JAVA_SHARED_DIRTY java_shared_dirty}
|
||||
* <li>{@link #METRIC_KEY_JAVA_SIZE java_size}
|
||||
* <li>{@link #METRIC_KEY_NATIVE_ALLOCATED native_allocated}
|
||||
* <li>{@link #METRIC_KEY_NATIVE_FREE native_free}
|
||||
* <li>{@link #METRIC_KEY_NATIVE_PRIVATE_DIRTY native_private_dirty}
|
||||
* <li>{@link #METRIC_KEY_NATIVE_PSS native_pss}
|
||||
* <li>{@link #METRIC_KEY_NATIVE_SHARED_DIRTY native_shared_dirty}
|
||||
* <li>{@link #METRIC_KEY_NATIVE_SIZE native_size}
|
||||
* <li>{@link #METRIC_KEY_GLOBAL_ALLOC_COUNT global_alloc_count}
|
||||
* <li>{@link #METRIC_KEY_GLOBAL_ALLOC_SIZE global_alloc_size}
|
||||
* <li>{@link #METRIC_KEY_GLOBAL_FREED_COUNT global_freed_count}
|
||||
* <li>{@link #METRIC_KEY_GLOBAL_FREED_SIZE global_freed_size}
|
||||
* <li>{@link #METRIC_KEY_OTHER_PRIVATE_DIRTY other_private_dirty}
|
||||
* <li>{@link #METRIC_KEY_OTHER_PSS other_pss}
|
||||
* <li>{@link #METRIC_KEY_OTHER_SHARED_DIRTY other_shared_dirty}
|
||||
* </ul>
|
||||
*/
|
||||
public Bundle endSnapshot() {
|
||||
endPerformanceSnapshot();
|
||||
if (mPerfWriter != null)
|
||||
mPerfWriter.writeEndSnapshot(mPerfSnapshot);
|
||||
return mPerfSnapshot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start measurement of user and cpu time.
|
||||
*
|
||||
* @param label description of code block between startTiming and
|
||||
* stopTiming, used to label output
|
||||
*/
|
||||
public void startTiming(String label) {
|
||||
if (mPerfWriter != null)
|
||||
mPerfWriter.writeStartTiming(label);
|
||||
mPerfMeasurement = new Bundle();
|
||||
mPerfMeasurement.putParcelableArrayList(
|
||||
METRIC_KEY_ITERATIONS, new ArrayList<Parcelable>());
|
||||
mExecTime = SystemClock.uptimeMillis();
|
||||
mCpuTime = Process.getElapsedCpuTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a measured segment, and start measuring the next segment. Returns
|
||||
* collected data in a Bundle object.
|
||||
*
|
||||
* @param label description of code block between startTiming and
|
||||
* addIteration, and between two calls to addIteration, used
|
||||
* to label output
|
||||
* @return Runtime metrics stored as key/value pairs. Values are of type
|
||||
* long, and keys include:
|
||||
* <ul>
|
||||
* <li>{@link #METRIC_KEY_LABEL label}
|
||||
* <li>{@link #METRIC_KEY_CPU_TIME cpu_time}
|
||||
* <li>{@link #METRIC_KEY_EXECUTION_TIME execution_time}
|
||||
* </ul>
|
||||
*/
|
||||
public Bundle addIteration(String label) {
|
||||
mCpuTime = Process.getElapsedCpuTime() - mCpuTime;
|
||||
mExecTime = SystemClock.uptimeMillis() - mExecTime;
|
||||
|
||||
Bundle iteration = new Bundle();
|
||||
iteration.putString(METRIC_KEY_LABEL, label);
|
||||
iteration.putLong(METRIC_KEY_EXECUTION_TIME, mExecTime);
|
||||
iteration.putLong(METRIC_KEY_CPU_TIME, mCpuTime);
|
||||
mPerfMeasurement.getParcelableArrayList(METRIC_KEY_ITERATIONS).add(iteration);
|
||||
|
||||
mExecTime = SystemClock.uptimeMillis();
|
||||
mCpuTime = Process.getElapsedCpuTime();
|
||||
return iteration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop measurement of user and cpu time.
|
||||
*
|
||||
* @param label description of code block between addIteration or
|
||||
* startTiming and stopTiming, used to label output
|
||||
* @return Runtime metrics stored in a bundle, including all iterations
|
||||
* between calls to startTiming and stopTiming. List of iterations
|
||||
* is keyed by {@link #METRIC_KEY_ITERATIONS iterations}.
|
||||
*/
|
||||
public Bundle stopTiming(String label) {
|
||||
addIteration(label);
|
||||
if (mPerfWriter != null)
|
||||
mPerfWriter.writeStopTiming(mPerfMeasurement);
|
||||
return mPerfMeasurement;
|
||||
}
|
||||
|
||||
/*
|
||||
* Starts tracking memory usage, binder transactions, and real & cpu timing.
|
||||
*/
|
||||
private void startPerformanceSnapshot() {
|
||||
// Create new snapshot
|
||||
mPerfSnapshot = new Bundle();
|
||||
|
||||
// Add initial binder counts
|
||||
Bundle binderCounts = getBinderCounts();
|
||||
for (String key : binderCounts.keySet()) {
|
||||
mPerfSnapshot.putLong("pre_" + key, binderCounts.getLong(key));
|
||||
}
|
||||
|
||||
// Force a GC and zero out the performance counters. Do this
|
||||
// before reading initial CPU/wall-clock times so we don't include
|
||||
// the cost of this setup in our final metrics.
|
||||
startAllocCounting();
|
||||
|
||||
// Record CPU time up to this point, and start timing. Note: this
|
||||
// must happen at the end of this method, otherwise the timing will
|
||||
// include noise.
|
||||
mSnapshotExecTime = SystemClock.uptimeMillis();
|
||||
mSnapshotCpuTime = Process.getElapsedCpuTime();
|
||||
}
|
||||
|
||||
/*
|
||||
* Stops tracking memory usage, binder transactions, and real & cpu timing.
|
||||
* Stores collected data as type long into Bundle object for reporting.
|
||||
*/
|
||||
private void endPerformanceSnapshot() {
|
||||
// Stop the timing. This must be done first before any other counting is
|
||||
// stopped.
|
||||
mSnapshotCpuTime = Process.getElapsedCpuTime() - mSnapshotCpuTime;
|
||||
mSnapshotExecTime = SystemClock.uptimeMillis() - mSnapshotExecTime;
|
||||
|
||||
stopAllocCounting();
|
||||
|
||||
long nativeMax = Debug.getNativeHeapSize() / 1024;
|
||||
long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
|
||||
long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
|
||||
|
||||
Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
|
||||
Debug.getMemoryInfo(memInfo);
|
||||
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
|
||||
long dalvikMax = runtime.totalMemory() / 1024;
|
||||
long dalvikFree = runtime.freeMemory() / 1024;
|
||||
long dalvikAllocated = dalvikMax - dalvikFree;
|
||||
|
||||
// Add final binder counts
|
||||
Bundle binderCounts = getBinderCounts();
|
||||
for (String key : binderCounts.keySet()) {
|
||||
mPerfSnapshot.putLong(key, binderCounts.getLong(key));
|
||||
}
|
||||
|
||||
// Add alloc counts
|
||||
Bundle allocCounts = getAllocCounts();
|
||||
for (String key : allocCounts.keySet()) {
|
||||
mPerfSnapshot.putLong(key, allocCounts.getLong(key));
|
||||
}
|
||||
|
||||
mPerfSnapshot.putLong(METRIC_KEY_EXECUTION_TIME, mSnapshotExecTime);
|
||||
mPerfSnapshot.putLong(METRIC_KEY_CPU_TIME, mSnapshotCpuTime);
|
||||
|
||||
mPerfSnapshot.putLong(METRIC_KEY_NATIVE_SIZE, nativeMax);
|
||||
mPerfSnapshot.putLong(METRIC_KEY_NATIVE_ALLOCATED, nativeAllocated);
|
||||
mPerfSnapshot.putLong(METRIC_KEY_NATIVE_FREE, nativeFree);
|
||||
mPerfSnapshot.putLong(METRIC_KEY_NATIVE_PSS, memInfo.nativePss);
|
||||
mPerfSnapshot.putLong(METRIC_KEY_NATIVE_PRIVATE_DIRTY, memInfo.nativePrivateDirty);
|
||||
mPerfSnapshot.putLong(METRIC_KEY_NATIVE_SHARED_DIRTY, memInfo.nativeSharedDirty);
|
||||
|
||||
mPerfSnapshot.putLong(METRIC_KEY_JAVA_SIZE, dalvikMax);
|
||||
mPerfSnapshot.putLong(METRIC_KEY_JAVA_ALLOCATED, dalvikAllocated);
|
||||
mPerfSnapshot.putLong(METRIC_KEY_JAVA_FREE, dalvikFree);
|
||||
mPerfSnapshot.putLong(METRIC_KEY_JAVA_PSS, memInfo.dalvikPss);
|
||||
mPerfSnapshot.putLong(METRIC_KEY_JAVA_PRIVATE_DIRTY, memInfo.dalvikPrivateDirty);
|
||||
mPerfSnapshot.putLong(METRIC_KEY_JAVA_SHARED_DIRTY, memInfo.dalvikSharedDirty);
|
||||
|
||||
mPerfSnapshot.putLong(METRIC_KEY_OTHER_PSS, memInfo.otherPss);
|
||||
mPerfSnapshot.putLong(METRIC_KEY_OTHER_PRIVATE_DIRTY, memInfo.otherPrivateDirty);
|
||||
mPerfSnapshot.putLong(METRIC_KEY_OTHER_SHARED_DIRTY, memInfo.otherSharedDirty);
|
||||
}
|
||||
|
||||
/*
|
||||
* Starts allocation counting. This triggers a gc and resets the counts.
|
||||
*/
|
||||
private static void startAllocCounting() {
|
||||
// Before we start trigger a GC and reset the debug counts. Run the
|
||||
// finalizers and another GC before starting and stopping the alloc
|
||||
// counts. This will free up any objects that were just sitting around
|
||||
// waiting for their finalizers to be run.
|
||||
Runtime.getRuntime().gc();
|
||||
Runtime.getRuntime().runFinalization();
|
||||
Runtime.getRuntime().gc();
|
||||
|
||||
Debug.resetAllCounts();
|
||||
|
||||
// start the counts
|
||||
Debug.startAllocCounting();
|
||||
}
|
||||
|
||||
/*
|
||||
* Stops allocation counting.
|
||||
*/
|
||||
private static void stopAllocCounting() {
|
||||
Runtime.getRuntime().gc();
|
||||
Runtime.getRuntime().runFinalization();
|
||||
Runtime.getRuntime().gc();
|
||||
Debug.stopAllocCounting();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a bundle with the current results from the allocation counting.
|
||||
*/
|
||||
private static Bundle getAllocCounts() {
|
||||
Bundle results = new Bundle();
|
||||
results.putLong(METRIC_KEY_GLOBAL_ALLOC_COUNT, Debug.getGlobalAllocCount());
|
||||
results.putLong(METRIC_KEY_GLOBAL_ALLOC_SIZE, Debug.getGlobalAllocSize());
|
||||
results.putLong(METRIC_KEY_GLOBAL_FREED_COUNT, Debug.getGlobalFreedCount());
|
||||
results.putLong(METRIC_KEY_GLOBAL_FREED_SIZE, Debug.getGlobalFreedSize());
|
||||
results.putLong(METRIC_KEY_GC_INVOCATION_COUNT, Debug.getGlobalGcInvocationCount());
|
||||
return results;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a bundle with the counts for various binder counts for this
|
||||
* process. Currently the only two that are reported are the number of send
|
||||
* and the number of received transactions.
|
||||
*/
|
||||
private static Bundle getBinderCounts() {
|
||||
Bundle results = new Bundle();
|
||||
results.putLong(METRIC_KEY_SENT_TRANSACTIONS, Debug.getBinderSentTransactions());
|
||||
results.putLong(METRIC_KEY_RECEIVED_TRANSACTIONS, Debug.getBinderReceivedTransactions());
|
||||
return results;
|
||||
}
|
||||
}
|
||||
32
core/java/android/test/TimedTest.java
Normal file
32
core/java/android/test/TimedTest.java
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.test;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* This annotation can be used on an {@link junit.framework.TestCase}'s test
|
||||
* methods. When the annotation is present, the test method is timed and the
|
||||
* results written through instrumentation output. It can also be used on the
|
||||
* class itself, which is equivalent to tagging all test methods with this
|
||||
* annotation.
|
||||
*
|
||||
* {@hide} Pending approval for public API.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TimedTest { }
|
||||
Reference in New Issue
Block a user