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
This commit is contained in:
Brian Carlstrom
2010-08-18 14:27:40 -07:00
parent 73ef5d4e2b
commit 1751086360
3 changed files with 52 additions and 44 deletions

View File

@@ -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;

View File

@@ -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.write(snapshot);
} finally {
out.close();
out = new PrintStream(new BufferedOutputStream(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 {
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.");
}
}
}

View File

@@ -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();