diff options
author | Brian Carlstrom <bdc@google.com> | 2010-12-01 15:40:38 -0800 |
---|---|---|
committer | Brian Carlstrom <bdc@google.com> | 2010-12-01 15:40:38 -0800 |
commit | def41ec2e88a70e63590117c93476276f8d0bf4c (patch) | |
tree | ca989293ee95e2c71616614c99f7e1691133dec1 /core/java/com/android | |
parent | 4449e4b6e2c09e527b97f46f58e0c0979cf3fe72 (diff) | |
download | frameworks_base-def41ec2e88a70e63590117c93476276f8d0bf4c.zip frameworks_base-def41ec2e88a70e63590117c93476276f8d0bf4c.tar.gz frameworks_base-def41ec2e88a70e63590117c93476276f8d0bf4c.tar.bz2 |
Resurrect SamplingProfilerIntegration
1.) Change from samples per second (persist.sys.profiler_hz) to
interval between samples (persist.sys.profiler_ms) to match
underlying SamplingProfiler API. This allows samples to be taken
less often than a second, which allows lower overhead for always
on profiling.
2.) Add persist.sys.profiler_depth to control the number of frames
kept. Currently defaults to 4 which is the default hprof depth,
but often 12 is necessary even in benchmarks to get a good idea
where time is being spent.
3.) Moved SNAPSHOT_DIR creation to initialization time instead of
checking it on every sample.
4.) Used ThreadFactory to provide human readable name to writeSnapshot
Executor thread.
5.) Fixed bug where writeZygoteSnapshot was calling wrong variant of
writeSnapshot causing profiling to prevent zygote startup. Renamed
underling private writeSnapshot to writeSnapshotFile to try to
prevent future confusion.
Change-Id: Ifcfc343816b19f13a6eef2cbf25cde334d8adc3b
Diffstat (limited to 'core/java/com/android')
-rw-r--r-- | core/java/com/android/internal/os/SamplingProfilerIntegration.java | 69 |
1 files changed, 33 insertions, 36 deletions
diff --git a/core/java/com/android/internal/os/SamplingProfilerIntegration.java b/core/java/com/android/internal/os/SamplingProfilerIntegration.java index c930c57..bfef275 100644 --- a/core/java/com/android/internal/os/SamplingProfilerIntegration.java +++ b/core/java/com/android/internal/os/SamplingProfilerIntegration.java @@ -27,6 +27,7 @@ import java.io.PrintStream; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.ThreadFactory; import android.content.pm.PackageInfo; import android.util.Log; @@ -43,27 +44,40 @@ public class SamplingProfilerIntegration { private static final boolean enabled; private static final Executor snapshotWriter; - private static final int samplingProfilerHz; - - /** Whether or not we've created the snapshots dir. */ - private static boolean dirMade = false; + private static final int samplingProfilerMilliseconds; + private static final int samplingProfilerDepth; /** Whether or not a snapshot is being persisted. */ private static final AtomicBoolean pending = new AtomicBoolean(false); static { - samplingProfilerHz = SystemProperties.getInt("persist.sys.profiler_hz", 0); - // Disabling this for now, as it crashes when enabled server-side. So adding - // a new property ("REALLY") for those wanting to test and fix it. - boolean really = SystemProperties.getInt("persist.sys.profiler_hz_REALLY", 0) > 0; - if (samplingProfilerHz > 0 && really) { - snapshotWriter = Executors.newSingleThreadExecutor(); - enabled = true; - Log.i(TAG, "Profiler is enabled. Sampling Profiler Hz: " + samplingProfilerHz); + samplingProfilerMilliseconds = SystemProperties.getInt("persist.sys.profiler_ms", 0); + samplingProfilerDepth = SystemProperties.getInt("persist.sys.profiler_depth", 4); + if (samplingProfilerMilliseconds > 0) { + File dir = new File(SNAPSHOT_DIR); + dir.mkdirs(); + // the directory needs to be writable to anybody to allow file writing + dir.setWritable(true, false); + // the directory needs to be executable to anybody to allow file creation + dir.setExecutable(true, false); + if (dir.isDirectory()) { + snapshotWriter = Executors.newSingleThreadExecutor(new ThreadFactory() { + public Thread newThread(Runnable r) { + return new Thread(r, TAG); + } + }); + enabled = true; + Log.i(TAG, "Profiling enabled. Sampling interval ms: " + + samplingProfilerMilliseconds); + } else { + snapshotWriter = null; + enabled = true; + Log.w(TAG, "Profiling setup failed. Could not create " + SNAPSHOT_DIR); + } } else { snapshotWriter = null; enabled = false; - Log.i(TAG, "Profiler is disabled."); + Log.i(TAG, "Profiling disabled."); } } @@ -85,8 +99,8 @@ public class SamplingProfilerIntegration { } ThreadGroup group = Thread.currentThread().getThreadGroup(); SamplingProfiler.ThreadSet threadSet = SamplingProfiler.newThreadGroupTheadSet(group); - INSTANCE = new SamplingProfiler(4, threadSet); // TODO parameter for depth - INSTANCE.start(1000/samplingProfilerHz); + INSTANCE = new SamplingProfiler(samplingProfilerDepth, threadSet); + INSTANCE.start(samplingProfilerMilliseconds); } /** @@ -106,25 +120,8 @@ public class SamplingProfilerIntegration { if (pending.compareAndSet(false, true)) { snapshotWriter.execute(new Runnable() { public void run() { - if (!dirMade) { - File dir = new File(SNAPSHOT_DIR); - dir.mkdirs(); - // the directory needs to be writable to anybody - dir.setWritable(true, false); - // the directory needs to be executable to anybody - // don't know why yet, but mode 723 would work, while - // mode 722 throws FileNotFoundExecption at line 151 - dir.setExecutable(true, false); - if (new File(SNAPSHOT_DIR).isDirectory()) { - dirMade = true; - } else { - Log.w(TAG, "Creation of " + SNAPSHOT_DIR + " failed."); - pending.set(false); - return; - } - } try { - writeSnapshot(SNAPSHOT_DIR, processName, packageInfo); + writeSnapshotFile(processName, packageInfo); } finally { pending.set(false); } @@ -140,7 +137,7 @@ public class SamplingProfilerIntegration { if (!enabled) { return; } - writeSnapshot("zygote", null); + writeSnapshotFile("zygote", null); INSTANCE.shutdown(); INSTANCE = null; } @@ -148,7 +145,7 @@ public class SamplingProfilerIntegration { /** * pass in PackageInfo to retrieve various values for snapshot header */ - private static void writeSnapshot(String dir, String processName, PackageInfo packageInfo) { + private static void writeSnapshotFile(String processName, PackageInfo packageInfo) { if (!enabled) { return; } @@ -161,7 +158,7 @@ public class SamplingProfilerIntegration { */ long start = System.currentTimeMillis(); String name = processName.replaceAll(":", "."); - String path = dir + "/" + name + "-" +System.currentTimeMillis() + ".snapshot"; + String path = SNAPSHOT_DIR + "/" + name + "-" +System.currentTimeMillis() + ".snapshot"; PrintStream out = null; try { out = new PrintStream(new BufferedOutputStream(new FileOutputStream(path))); |