SamplingProfilerIntegrationpublic class SamplingProfilerIntegration extends Object Integrates the framework with Dalvik's sampling profiler. |
Fields Summary |
---|
private static final String | TAG | public static final String | SNAPSHOT_DIR | private static final boolean | enabled | private static final Executor | snapshotWriter | private static final int | samplingProfilerMilliseconds | private static final int | samplingProfilerDepth | private static final AtomicBoolean | pendingWhether or not a snapshot is being persisted. | private static dalvik.system.profiler.SamplingProfiler | samplingProfiler | private static long | startMillis |
Methods Summary |
---|
private static void | generateSnapshotHeader(java.lang.String processName, android.content.pm.PackageInfo packageInfo, java.io.PrintStream out)generate header for snapshots, with the following format
(like an HTTP header but without the \r):
Version: \n
Process: \n
Package: \n
Package-Version: \n
Build: \n
\n
// profiler version
out.println("Version: 3");
out.println("Process: " + processName);
if (packageInfo != null) {
out.println("Package: " + packageInfo.packageName);
out.println("Package-Version: " + packageInfo.versionCode);
}
out.println("Build: " + Build.FINGERPRINT);
// single blank line means the end of snapshot header.
out.println();
| public static boolean | isEnabled()Is profiling enabled?
return enabled;
| public static void | start()Starts the profiler if profiling is enabled.
if (!enabled) {
return;
}
if (samplingProfiler != null) {
Log.e(TAG, "SamplingProfilerIntegration already started at " + new Date(startMillis));
return;
}
ThreadGroup group = Thread.currentThread().getThreadGroup();
SamplingProfiler.ThreadSet threadSet = SamplingProfiler.newThreadGroupThreadSet(group);
samplingProfiler = new SamplingProfiler(samplingProfilerDepth, threadSet);
samplingProfiler.start(samplingProfilerMilliseconds);
startMillis = System.currentTimeMillis();
| public static void | writeSnapshot(java.lang.String processName, android.content.pm.PackageInfo packageInfo)Writes a snapshot if profiling is enabled.
if (!enabled) {
return;
}
if (samplingProfiler == null) {
Log.e(TAG, "SamplingProfilerIntegration is not started");
return;
}
/*
* If we're already writing a snapshot, don't bother enqueueing another
* request right now. This will reduce the number of individual
* snapshots and in turn the total amount of memory consumed (one big
* snapshot is smaller than N subset snapshots).
*/
if (pending.compareAndSet(false, true)) {
snapshotWriter.execute(new Runnable() {
public void run() {
try {
writeSnapshotFile(processName, packageInfo);
} finally {
pending.set(false);
}
}
});
}
| private static void | writeSnapshotFile(java.lang.String processName, android.content.pm.PackageInfo packageInfo)pass in PackageInfo to retrieve various values for snapshot header
if (!enabled) {
return;
}
samplingProfiler.stop();
/*
* We use the global start time combined with the process name
* as a unique ID. We can't use a counter because processes
* restart. This could result in some overlap if we capture
* two snapshots in rapid succession.
*/
String name = processName.replaceAll(":", ".");
String path = SNAPSHOT_DIR + "/" + name + "-" + startMillis + ".snapshot";
long start = System.currentTimeMillis();
OutputStream outputStream = null;
try {
outputStream = new BufferedOutputStream(new FileOutputStream(path));
PrintStream out = new PrintStream(outputStream);
generateSnapshotHeader(name, packageInfo, out);
if (out.checkError()) {
throw new IOException();
}
BinaryHprofWriter.write(samplingProfiler.getHprofData(), outputStream);
} catch (IOException e) {
Log.e(TAG, "Error writing snapshot to " + path, e);
return;
} finally {
IoUtils.closeQuietly(outputStream);
}
// set file readable to the world so that SamplingProfilerService
// can put it to dropbox
new File(path).setReadable(true, false);
long elapsed = System.currentTimeMillis() - start;
Log.i(TAG, "Wrote snapshot " + path + " in " + elapsed + "ms.");
samplingProfiler.start(samplingProfilerMilliseconds);
| public static void | writeZygoteSnapshot()Writes the zygote's snapshot to internal storage if profiling is enabled.
if (!enabled) {
return;
}
writeSnapshotFile("zygote", null);
samplingProfiler.shutdown();
samplingProfiler = null;
startMillis = 0;
|
|