I am a beginner for Android develop. And currently I am looking for an automatic way to dump memory when out of memory error happens. I read that adding -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/some/path to your jvm args so that when it runs out of memory it will dump out the heap. But I couldn't find where to set it. Does anyone know it? thanks a lot.
Asked
Active
Viewed 1,010 times
1 Answers
1
The flag you listed is for an Oracle VM, not Dalvik.
There's no equivalent flag, but you can implement similar behavior. The android.os.Debug.dumpHprofData()
method will write the current heap dump to a file you specify. When combined with an UncaughtExceptionHandler
set by Thread.setDefaultUncaughtExceptionHandler()
, you can catch OOM in any thread and handle the reporting yourself. (Just don't get too carried away... you are out of memory after all.)
You will need to chain your handler to the Android system one -- see also Ideal way to set global uncaught exception Handler in Android.
A threw together a quick example of what this would look like.
-
Thanks fadden, I followed your way, but seems like the global uncaught exception handler can't catch the OOM exception, though other exceptions such as null pointer exception can be caught. Not sure I missed something, or this way is not feasible. – bettermanlu May 06 '13 at 14:34
-
1It may not work. If you're utterly out of memory, you can get OOMs trying to report the OOM. If you failed allocating something moderately large (like a bitmap), you'll have plenty of room. The `logcat` output should provide some details. – fadden May 06 '13 at 18:15
-
It's a quite simple demo, creating a static hashmap, then saving the bitmap objects into it to make it OOM. the code snippet is as below: for (int i = 0; i < 10; i++) { String bitMapIdOOM = bitmapId + "." + i; Bitmap mBitmapOOM = BitmapFactory.decodeResource(getResources(), R.drawable.bike); sBitmapCache.put(bitMapIdOOM, mBitmapOOM); } the logcat shows as below, it's asking for about 8M bytes. So this means it should have enough room. E/dalvikvm-heap(11636): Out of memory on a 8294416-byte allocation. @fadden, any suggestion? – bettermanlu May 07 '13 at 02:43
-
Another way might be creating a separate process monitor, monitoring the target app. When it OOMs, process monitor halts it and dumps its heap. But I am not sure how to implement it. :-) – bettermanlu May 07 '13 at 09:35
-
1Well, you can attach a debugger (like the one that's part of Eclipse), and configure an "exception breakpoint" from the Run menu. Set it to break on `OutOfMemoryError`, for both caught and uncaught exceptions. At that point you *should* be able to evaluate the `dumpHprofData` method as an expression (Eclipse can execute arbitrary code when you're stopped at a breakpoint). You can also try to use the `java.lang.Runtime.freeMemory` call to guess when you're running low and dump the heap ahead of the OOM. – fadden May 07 '13 at 14:44
-
Thanks a lot fadden. I will give it a try tomorrow on Eclipse. My aim is to find or write an app that can be used convinently on the cellphone without requiring a wire connected the phone with a computer, without target app's source code. If I want to write my own debugger app like eclipse does, which starts another app or just invading into another running app to catch its uncaught exception. Is it possible? If so, do you know any material that I can refer to? Thanks a lot. – bettermanlu May 07 '13 at 15:36
-
I created a code sample for the original idea and added a link to it in the answer. – fadden May 07 '13 at 17:36