Loading core/java/android/app/ActivityThread.java +4 −5 Original line number Diff line number Diff line Loading @@ -1130,8 +1130,8 @@ public final class ActivityThread { if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + msg.what); } void maybeSnapshot() { if (mBoundApplication != null) { private void maybeSnapshot() { if (mBoundApplication != null && SamplingProfilerIntegration.isEnabled()) { // convert the *private* ActivityThread.PackageInfo to *public* known // android.content.pm.PackageInfo String packageName = mBoundApplication.info.mPackageName; Loading Loading @@ -3396,8 +3396,7 @@ public final class ActivityThread { } final void handleLowMemory() { ArrayList<ComponentCallbacks> callbacks = new ArrayList<ComponentCallbacks>(); ArrayList<ComponentCallbacks> callbacks; synchronized (mPackages) { callbacks = collectComponentCallbacksLocked(true, null); Loading core/java/com/android/internal/os/SamplingProfilerIntegration.java +37 −19 Original line number Diff line number Diff line Loading @@ -20,13 +20,15 @@ import android.content.pm.PackageInfo; import android.os.Build; import android.os.SystemProperties; import android.util.Log; import dalvik.system.profiler.AsciiHprofWriter; import dalvik.system.profiler.BinaryHprofWriter; import dalvik.system.profiler.SamplingProfiler; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.util.Date; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; Loading Loading @@ -81,7 +83,8 @@ public class SamplingProfilerIntegration { } } private static SamplingProfiler INSTANCE; private static SamplingProfiler samplingProfiler; private static long startMillis; /** * Is profiling enabled? Loading @@ -97,10 +100,16 @@ public class SamplingProfilerIntegration { 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.newThreadGroupTheadSet(group); INSTANCE = new SamplingProfiler(samplingProfilerDepth, threadSet); INSTANCE.start(samplingProfilerMilliseconds); samplingProfiler = new SamplingProfiler(samplingProfilerDepth, threadSet); samplingProfiler.start(samplingProfilerMilliseconds); startMillis = System.currentTimeMillis(); } /** Loading @@ -110,6 +119,10 @@ public class SamplingProfilerIntegration { 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 Loading Loading @@ -138,8 +151,9 @@ public class SamplingProfilerIntegration { return; } writeSnapshotFile("zygote", null); INSTANCE.shutdown(); INSTANCE = null; samplingProfiler.shutdown(); samplingProfiler = null; startMillis = 0; } /** Loading @@ -149,40 +163,44 @@ public class SamplingProfilerIntegration { if (!enabled) { return; } INSTANCE.stop(); samplingProfiler.stop(); /* * We use the current time 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. * 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. */ long start = System.currentTimeMillis(); String name = processName.replaceAll(":", "."); String path = SNAPSHOT_DIR + "/" + name + "-" +System.currentTimeMillis() + ".snapshot"; PrintStream out = null; String path = SNAPSHOT_DIR + "/" + name + "-" + startMillis + ".snapshot"; long start = System.currentTimeMillis(); OutputStream outputStream = null; try { out = new PrintStream(new BufferedOutputStream(new FileOutputStream(path))); outputStream = new BufferedOutputStream(new FileOutputStream(path)); PrintStream out = new PrintStream(outputStream); generateSnapshotHeader(name, packageInfo, out); new AsciiHprofWriter(INSTANCE.getHprofData(), out).write(); 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(out); 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 for " + name + " in " + elapsed + "ms."); Log.i(TAG, "Wrote snapshot " + path + " in " + elapsed + "ms."); samplingProfiler.start(samplingProfilerMilliseconds); } /** * generate header for snapshots, with the following format (like http header): * generate header for snapshots, with the following format * (like an HTTP header but without the \r): * * Version: <version number of profiler>\n * Process: <process name>\n Loading @@ -195,7 +213,7 @@ public class SamplingProfilerIntegration { private static void generateSnapshotHeader(String processName, PackageInfo packageInfo, PrintStream out) { // profiler version out.println("Version: 2"); out.println("Version: 3"); out.println("Process: " + processName); if (packageInfo != null) { out.println("Package: " + packageInfo.packageName); Loading Loading
core/java/android/app/ActivityThread.java +4 −5 Original line number Diff line number Diff line Loading @@ -1130,8 +1130,8 @@ public final class ActivityThread { if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + msg.what); } void maybeSnapshot() { if (mBoundApplication != null) { private void maybeSnapshot() { if (mBoundApplication != null && SamplingProfilerIntegration.isEnabled()) { // convert the *private* ActivityThread.PackageInfo to *public* known // android.content.pm.PackageInfo String packageName = mBoundApplication.info.mPackageName; Loading Loading @@ -3396,8 +3396,7 @@ public final class ActivityThread { } final void handleLowMemory() { ArrayList<ComponentCallbacks> callbacks = new ArrayList<ComponentCallbacks>(); ArrayList<ComponentCallbacks> callbacks; synchronized (mPackages) { callbacks = collectComponentCallbacksLocked(true, null); Loading
core/java/com/android/internal/os/SamplingProfilerIntegration.java +37 −19 Original line number Diff line number Diff line Loading @@ -20,13 +20,15 @@ import android.content.pm.PackageInfo; import android.os.Build; import android.os.SystemProperties; import android.util.Log; import dalvik.system.profiler.AsciiHprofWriter; import dalvik.system.profiler.BinaryHprofWriter; import dalvik.system.profiler.SamplingProfiler; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.util.Date; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; Loading Loading @@ -81,7 +83,8 @@ public class SamplingProfilerIntegration { } } private static SamplingProfiler INSTANCE; private static SamplingProfiler samplingProfiler; private static long startMillis; /** * Is profiling enabled? Loading @@ -97,10 +100,16 @@ public class SamplingProfilerIntegration { 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.newThreadGroupTheadSet(group); INSTANCE = new SamplingProfiler(samplingProfilerDepth, threadSet); INSTANCE.start(samplingProfilerMilliseconds); samplingProfiler = new SamplingProfiler(samplingProfilerDepth, threadSet); samplingProfiler.start(samplingProfilerMilliseconds); startMillis = System.currentTimeMillis(); } /** Loading @@ -110,6 +119,10 @@ public class SamplingProfilerIntegration { 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 Loading Loading @@ -138,8 +151,9 @@ public class SamplingProfilerIntegration { return; } writeSnapshotFile("zygote", null); INSTANCE.shutdown(); INSTANCE = null; samplingProfiler.shutdown(); samplingProfiler = null; startMillis = 0; } /** Loading @@ -149,40 +163,44 @@ public class SamplingProfilerIntegration { if (!enabled) { return; } INSTANCE.stop(); samplingProfiler.stop(); /* * We use the current time 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. * 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. */ long start = System.currentTimeMillis(); String name = processName.replaceAll(":", "."); String path = SNAPSHOT_DIR + "/" + name + "-" +System.currentTimeMillis() + ".snapshot"; PrintStream out = null; String path = SNAPSHOT_DIR + "/" + name + "-" + startMillis + ".snapshot"; long start = System.currentTimeMillis(); OutputStream outputStream = null; try { out = new PrintStream(new BufferedOutputStream(new FileOutputStream(path))); outputStream = new BufferedOutputStream(new FileOutputStream(path)); PrintStream out = new PrintStream(outputStream); generateSnapshotHeader(name, packageInfo, out); new AsciiHprofWriter(INSTANCE.getHprofData(), out).write(); 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(out); 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 for " + name + " in " + elapsed + "ms."); Log.i(TAG, "Wrote snapshot " + path + " in " + elapsed + "ms."); samplingProfiler.start(samplingProfilerMilliseconds); } /** * generate header for snapshots, with the following format (like http header): * generate header for snapshots, with the following format * (like an HTTP header but without the \r): * * Version: <version number of profiler>\n * Process: <process name>\n Loading @@ -195,7 +213,7 @@ public class SamplingProfilerIntegration { private static void generateSnapshotHeader(String processName, PackageInfo packageInfo, PrintStream out) { // profiler version out.println("Version: 2"); out.println("Version: 3"); out.println("Process: " + processName); if (packageInfo != null) { out.println("Package: " + packageInfo.packageName); Loading