Heap snapshot capture during android OutOfMemory

Source: Internet
Author: User

(Here we will not teach you how to analyze heap snapshots, but how to capture them at critical times)
First, let's talk about how to capture heap snapshots when the program does not crash.
We should all know that this feature is provided in ddms.

See
First, select a process and click the Update Heap button (next to the little green bug). Then you can see the heap usage.
If you want to take out the detailed analysis of the snapshot, you can click the Dump HPROF File button to save it to your computer. Use the android-sdk/tools/hprof-conv tool to convert the file and use MAT for analysis.
[Java]
Hprof-conv '/home/su1216/data. hprof'/home/su1216/data_ OK .hprof'
In this case, MAT can directly open the data_ OK .hprof file.


What should we do if we want a memory snapshot for OOM? We can't stare at the mobile phone while staring at the computer. OOM immediately captures memory snapshots, which is obviously unrealistic.
If OOM is not often reproduced, we will miss many bugs and waste a lot of time.

Here is a method for capturing heap snapshots during OOM.
Because the heap snapshot in OOM is large, I chose to save the captured memory snapshot to the SD card. Therefore, I must have the permission to write data to external storage.
[Xml]
<Uses-permission android: name = "android. permission. WRITE_EXTERNAL_STORAGE"/>
Then we need to implement the UncaughtExceptionHandler interface.
Remember to set Handler that does not capture exceptions and set it to yourself.
When an exception occurs, the uncaughtException method is called, so we can capture the memory snapshot here.
[Java]
Import java. lang. Thread. UncaughtExceptionHandler;
 
Import android. OS. Debug;
Import android. OS. Environment;
Import android. util. Log;
 
Public class CrashHandler implements UncaughtExceptionHandler {
 
Public static final String TAG = "CrashHandler ";
Private Thread. UncaughtExceptionHandler mDefaultHandler;
Private static final String OOM = "java. lang. OutOfMemoryError ";
Private static final String HPROF_FILE_PATH = Environment. getExternalStorageDirectory (). getPath () + "/data. hprof ";
 
Private static CrashHandler sCrashHandler;
 
Private CrashHandler (){}
 
Public synchronized static CrashHandler getInstance (){
If (sCrashHandler = null ){
SCrashHandler = new CrashHandler ();
}
Return sCrashHandler;
}
 
Public void init (){
MDefaultHandler = Thread. getDefaultUncaughtExceptionHandler ();
Thread. setDefaultUncaughtExceptionHandler (this );
}
 
Public static boolean isOOM (Throwable throwable ){
Log. d (TAG, "getName:" + throwable. getClass (). getName ());
If (OOM. equals (throwable. getClass (). getName ())){
Return true;
} Else {
Throwable cause = throwable. getCause ();
If (cause! = Null ){
Return isOOM (cause );
}
Return false;
}
}

Public void uncaughtException (Thread thread, Throwable throwable ){
If (isOOM (throwable )){
Try {
Debug. dumpHprofData (HPROF_FILE_PATH );
} Catch (Exception e ){
Log. e (TAG, "couldn't dump hprof", e );
}
}
 
If (mDefaultHandler! = Null ){
MDefaultHandler. uncaughtException (thread, throwable );
} Else {
Android. OS. Process. killProcess (android. OS. Process. myPid ());
System. exit (1 );
}
}
}
The most critical code is this sentence.
[Java]
Debug. dumpHprofData (<span style = "font-family: Monaco, 'dejavu Sans mono', 'bitstream Vera Sans mono', Consolas, 'courier new', monospace; line-height: 18px; text-align: left; background-color: rgb (250,250,250); "> HPROF_FILE_PATH </span> );
This allows us to control the timing of capturing heap snapshots.
OutOfMemoryError is a system-level error, so it should not be captured in general.
In case someone captures the vulnerability and throws an exception that calls the initCause method again, we should also intercept it and fix the bug instead of hiding it.

Here we only need to capture the memory snapshot. After the task is finished, remember to submit the throwable to the system for processing.
[Java]
MDefaultHandler. uncaughtException (thread, throwable );
Of course, we can actually shield the force close dialog box in this place, which is amazing...

By the way, how can I check the memory limit of android apps?
Each mobile phone has different restrictions on applications. After all, the hardware is different. We can use the following method to view the maximum memory available for individual applications:
Adb shell getprop | grep heap
[Dalvik. vm. heapgrowthlimit]: [64 m]
[Dalvik. vm. heapsize]: [256 m]
[Dalvik. vm. heapstartsize]: [8 m]
Enter the command and check the preceding results.
[Dalvik. vm. heapstartsize]: [8 m]: Start heap = 8 m for process allocation
[Dalvik. vm. heapgrowthlimit]: [64 m]: process can be allocated to a maximum of 64 m
[Dalvik. vm. heapsize]: [256 m]: maximum memory allocated to a single virtual machine = 256 m

You can modify the above parameters in build. prop.
Build. prop in system, pull out and modify it, and then push it back, reboot.


We can estimate the heap size and check whether the remaining space on the SD card is sufficient.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.