Is there a way to force an Android process to create a bunch of heaps on an OutOfMemoryError?

The Sun JVM supports the -XX:+HeapDumpOnOutOfMemoryError parameter to unload the heap whenever the heap ends from the java process.

Is there a similar version on Android that will dump a bunch of Android applications in OutOfMemoryException? When using DDMS manually, it can be difficult to try to execute it correctly.

+17
android out-of-memory dump hprof
May 25 '11 at 22:34
source share
3 answers

To extend the response to CommonsWare:

I have no idea if this works, but you can try adding a top-level exception handler , and there it asks for a bunch of dumps if it's OutOfMemoryError .

I successfully executed his offer in my Android app with the following code:

 public class MyActivity extends Activity { public static class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { @Override public void uncaughtException(Thread thread, Throwable ex) { Log.e("UncaughtException", "Got an uncaught exception: "+ex.toString()); if(ex.getClass().equals(OutOfMemoryError.class)) { try { android.os.Debug.dumpHprofData("/sdcard/dump.hprof"); } catch (IOException e) { e.printStackTrace(); } } ex.printStackTrace(); } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Thread.currentThread().setUncaughtExceptionHandler(new MyUncaughtExceptionHandler()); } } 

After creating the dump, you need to copy it from the phone to the computer: Click "Turn on USB storage" on the phone, find the file and copy it to your hard drive.

Then, if you want to use the Eclipse memory analyzer (MAT) to analyze the file, you will need to hide the file: hprof-conv.exe dump.hprof dump-conv.hprof (hprof-conv is under android-sdk/tools )

Finally open dump-conv.hprof with MAT

+25
Aug 03 '11 at 20:22
source share

I have no idea if this works, but you can try adding a top-level exception handler , and there it asks for a bunch of dumps if it's OutOfMemoryError .

+8
May 25 '11 at 23:43
source share

Here is an improved version. In addition to the initial implementation, this implementation also supports:

  • Resolving memory errors in all threads (not only in the main thread)
  • Identification of errors in memory, even if it is hidden inside another error. In some cases, the Out of Memory error is encapsulated inside a Runtime error.
  • Calling the original default exception handler.
  • Works only in DEBUG builds.

Usage: Call the static initialize method in the Application class onCreate .

 package test; import java.io.File; import java.io.IOException; import java.lang.Thread.UncaughtExceptionHandler; import android.os.Environment; import android.util.Log; import com.example.test1.BuildConfig; public class OutOfMemoryDumper implements Thread.UncaughtExceptionHandler { private static final String TAG = "OutOfMemoryDumper"; private static final String FILE_PREFIX = "OOM-"; private static final OutOfMemoryDumper instance = new OutOfMemoryDumper(); private UncaughtExceptionHandler oldHandler; /** * Call this method to initialize the OutOfMemoryDumper when your * application is first launched. */ public static void initialize() { // Only works in DEBUG builds if (BuildConfig.DEBUG) { instance.setup(); } } /** * Keep the constructor private to ensure we only have one instance */ private OutOfMemoryDumper() { } private void setup() { // Checking if the dumper isn't already the default handler if (!(Thread.getDefaultUncaughtExceptionHandler() instanceof OutOfMemoryDumper)) { // Keep the old default handler as we are going to use it later oldHandler = Thread.getDefaultUncaughtExceptionHandler(); // Redirect uncaught exceptions to this class Thread.setDefaultUncaughtExceptionHandler(this); } Log.v(TAG, "OutOfMemoryDumper is ready"); } @Override public void uncaughtException(Thread thread, Throwable ex) { Log.e(TAG, "Uncaught exception: " + ex); Log.e(TAG, "Caused by: " + ex.getCause()); // Checking if the exception or the original cause for the exception is // an out of memory error if (ex.getClass().equals(OutOfMemoryError.class) || (ex.getCause() != null && ex.getCause().getClass() .equals(OutOfMemoryError.class))) { // Checking if the external storage is mounted and available if (isExternalStorageWritable()) { try { // Building the path to the new file File f = Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); long time = System.currentTimeMillis(); String dumpPath = f.getAbsolutePath() + "/" + FILE_PREFIX + time + ".hprof"; Log.i(TAG, "Dumping hprof data to: " + dumpPath); android.os.Debug.dumpHprofData(dumpPath); } catch (IOException ioException) { Log.e(TAG,"Failed to dump hprof data. " + ioException.toString()); ioException.printStackTrace(); } } } // Invoking the original default exception handler (if exists) if (oldHandler != null) { Log.v(TAG, "Invoking the original uncaught exception handler"); oldHandler.uncaughtException(thread, ex); } } /** * Checks if external storage is available for read and write * * @return true if the external storage is available */ private boolean isExternalStorageWritable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { return true; } Log.w(TAG,"The external storage isn't available. hprof data won't be dumped! (state=" + state + ")"); return false; } } 
+8
Sep 29 '14 at 21:47
source share



All Articles