diff options
| author | Brian Carlstrom <bdc@google.com> | 2010-08-18 14:27:40 -0700 |
|---|---|---|
| committer | Brian Carlstrom <bdc@google.com> | 2010-09-01 10:17:25 -0700 |
| commit | 1751086360056bc60d00f2ed2988bc82be9e7bd9 (patch) | |
| tree | 6f18642b550b5a75fe06f34ce18b80bf4e0e0678 /core | |
| parent | 73ef5d4e2bcbf28ccb84580439f2f79d5cea1ec7 (diff) | |
| download | frameworks_base-1751086360056bc60d00f2ed2988bc82be9e7bd9.zip frameworks_base-1751086360056bc60d00f2ed2988bc82be9e7bd9.tar.gz frameworks_base-1751086360056bc60d00f2ed2988bc82be9e7bd9.tar.bz2 | |
New Java-based SamplingProfiler
Summary:
- libcore: new Java based SamplingProfiler
- dalvik: remove old SamplingProfiler native bits
- frameworks/base: New placeholder SamplingProfilerIntegration
- vendor/google: remove old profiler snapshot parsing code
Details:
libcore
A new 100% Java SamplingProfiler. While it has more overhead that
the old native one, the new one can actually collect more than the
current PC and frame pointer, so you can get useful context of
where your app is spending time. It currently provides ASCII hprof
format output for use with tools like PerfAnal
dalvik/src/main/java/dalvik/system/SamplingProfiler.java
Unit test for the new SamplingProfiler
dalvik/src/test/java/dalvik/system/SamplingProfilerTest.java
Add core-tests-dalvik
JavaLibrary.mk
dalvik
Removing native code that supported the old SamplingProfiler
vm/Dvm.mk
vm/native/InternalNative.c
vm/native/dalvik_system_SamplingProfiler.c
frameworks/base
Placeholder SamplingProfilerIntegration. Later plans include
generating EventStackTrace protobufs.
New SamplingProfiler does not have a global instance, so
SamplingProfilerIntegration provides one in INSTANCE. Old binary
snapshot format is temporily replaced with ASCII hprof data.
core/java/com/android/internal/os/SamplingProfilerIntegration.java
Simplified interface for zygote profile snapshotting
core/java/com/android/internal/os/ZygoteInit.java
Current SamplingProfilerIntegration does not track event loop
explicitly, but hprof information does include thread information.
core/java/android/app/ActivityThread.java
vendor/google
Removing code for parsing old SamplingProfiler snapshot format
tools/samplingprofiler/Android.mk
tools/samplingprofiler/NOTICE
tools/samplingprofiler/profiler.iml
tools/samplingprofiler/profiler.ipr
tools/samplingprofiler/pull-snapshots.sh
tools/samplingprofiler/sorttable.js
tools/samplingprofiler/src/com/android/profiler/PrintHtml.java
Diffstat (limited to 'core')
| -rw-r--r-- | core/java/android/app/ActivityThread.java | 4 | ||||
| -rw-r--r-- | core/java/com/android/internal/os/SamplingProfilerIntegration.java | 82 | ||||
| -rw-r--r-- | core/java/com/android/internal/os/ZygoteInit.java | 8 |
3 files changed, 51 insertions, 43 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index ca6fc8a..373142d 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -837,10 +837,6 @@ public final class ActivityThread { } private final class H extends Handler { - private H() { - SamplingProfiler.getInstance().setEventThread(mLooper.getThread()); - } - public static final int LAUNCH_ACTIVITY = 100; public static final int PAUSE_ACTIVITY = 101; public static final int PAUSE_ACTIVITY_FINISHING= 102; diff --git a/core/java/com/android/internal/os/SamplingProfilerIntegration.java b/core/java/com/android/internal/os/SamplingProfilerIntegration.java index 5f5c7a4..a3efbc8 100644 --- a/core/java/com/android/internal/os/SamplingProfilerIntegration.java +++ b/core/java/com/android/internal/os/SamplingProfilerIntegration.java @@ -18,10 +18,12 @@ package com.android.internal.os; import dalvik.system.SamplingProfiler; +import java.io.BufferedOutputStream; import java.io.File; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; -import java.io.FileNotFoundException; +import java.io.PrintStream; import java.util.concurrent.Executor; import java.util.concurrent.Executors; @@ -48,6 +50,8 @@ public class SamplingProfilerIntegration { } } + private static SamplingProfiler INSTANCE; + /** * Is profiling enabled? */ @@ -59,8 +63,13 @@ public class SamplingProfilerIntegration { * Starts the profiler if profiling is enabled. */ public static void start() { - if (!enabled) return; - SamplingProfiler.getInstance().start(10); + if (!enabled) { + return; + } + ThreadGroup group = Thread.currentThread().getThreadGroup(); + SamplingProfiler.ThreadSet threadSet = SamplingProfiler.newThreadGroupTheadSet(group); + INSTANCE = new SamplingProfiler(4, threadSet); + INSTANCE.start(10); } /** Whether or not we've created the snapshots dir. */ @@ -73,7 +82,9 @@ public class SamplingProfilerIntegration { * Writes a snapshot to the SD card if profiling is enabled. */ public static void writeSnapshot(final String name) { - if (!enabled) return; + if (!enabled) { + return; + } /* * If we're already writing a snapshot, don't bother enqueing another @@ -109,18 +120,22 @@ public class SamplingProfilerIntegration { * Writes the zygote's snapshot to internal storage if profiling is enabled. */ public static void writeZygoteSnapshot() { - if (!enabled) return; + if (!enabled) { + return; + } String dir = "/data/zygote/snapshots"; new File(dir).mkdirs(); writeSnapshot(dir, "zygote"); + INSTANCE.shutdown(); + INSTANCE = null; } private static void writeSnapshot(String dir, String name) { - byte[] snapshot = SamplingProfiler.getInstance().snapshot(); - if (snapshot == null) { + if (!enabled) { return; } + INSTANCE.stop(); /* * We use the current time as a unique ID. We can't use a counter @@ -128,39 +143,40 @@ public class SamplingProfilerIntegration { * we capture two snapshots in rapid succession. */ long start = System.currentTimeMillis(); - String path = dir + "/" + name.replace(':', '.') + "-" + + String path = dir + "/" + name.replace(':', '.') + "-" + System.currentTimeMillis() + ".snapshot"; - try { - // Try to open the file a few times. The SD card may not be mounted. - FileOutputStream out; - int count = 0; - while (true) { - try { - out = new FileOutputStream(path); - break; - } catch (FileNotFoundException e) { - if (++count > 3) { - Log.e(TAG, "Could not open " + path + "."); - return; - } - // Sleep for a bit and then try again. - try { - Thread.sleep(2500); - } catch (InterruptedException e1) { /* ignore */ } + // Try to open the file a few times. The SD card may not be mounted. + PrintStream out; + int count = 0; + while (true) { + try { + out = new PrintStream(new BufferedOutputStream(new FileOutputStream(path))); + break; + } catch (FileNotFoundException e) { + if (++count > 3) { + Log.e(TAG, "Could not open " + path + "."); + return; } - } - try { - out.write(snapshot); - } finally { - out.close(); + // Sleep for a bit and then try again. + try { + Thread.sleep(2500); + } catch (InterruptedException e1) { /* ignore */ } } + } + + try { + INSTANCE.writeHprofData(out); + } finally { + out.close(); + } + if (out.checkError()) { + Log.e(TAG, "Error writing snapshot."); + } else { long elapsed = System.currentTimeMillis() - start; Log.i(TAG, "Wrote snapshot for " + name - + " in " + elapsed + "ms."); - } catch (IOException e) { - Log.e(TAG, "Error writing snapshot.", e); + + " in " + elapsed + "ms."); } } } diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 9fcd3f5..a409ec8 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -575,12 +575,8 @@ public class ZygoteInit { EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis()); - if (SamplingProfilerIntegration.isEnabled()) { - SamplingProfiler sp = SamplingProfiler.getInstance(); - sp.pause(); - SamplingProfilerIntegration.writeZygoteSnapshot(); - sp.shutDown(); - } + // Finish profiling the zygote initialization. + SamplingProfilerIntegration.writeZygoteSnapshot(); // Do an initial gc to clean up after startup gc(); |
