Android Source Series < 13 > Deep understanding of Leakcanary's memory leak detection mechanism from the source point of view (medium)

Source: Internet
Author: User

Reprint Please specify source: http://blog.csdn.net/llew2011/article/details/52958563

In the previous article Android source line < 12 > in-depth understanding of Leakcanary's memory leak detection mechanism from the source point of view (above) Mainly introduces the knowledge of Java memory allocation and the various memory leaks that may be encountered in the development of Android, and gives the corresponding solution, if you have not read the previous article, it is recommended to click here to read, This article will show you how to use the square open source Leakcanary library in our application to detect memory leaks in your application, and if you are already familiar with the use of leakcanary, skip this article (*^__^*) ...

To introduce the translation from the English Leakcanary:detect all memory leaks!, the original is here.

Java.lang.OutOfMemoryError at        android.graphics.Bitmap.nativeCreate (bitmap.java:-2)        at Android.graphics.Bitmap.createBitmap (bitmap.java:689) at        Com.squareup.ui.SignView.createSignatureBitmap ( signview.java:121)
no one likes outofmemoryerror.

In the Square register, on the signature page we draw the customer's signature on the bitmap cache, which is almost as large as the size of the screen, and often triggers outofmemoryerror when creating this bitmap object, or Oom.

At the time, we tried some solutions, but none of them solved the problem:

    • Use Bitmap.Config.ALPHA_8 because the signature is only black.
    • Capture OutOfMemoryError, try GC and try again (inspired by gcutils).
    • We have not thought of creating bitmap outside of Java heap memory, and it is hard for us to fresco that the library does not exist.
It's a wrong path.

In fact, the size of the bitmap is not the real problem, when the memory is tight, everywhere is likely to trigger oom, in the creation of large objects, such as bitmap, it is more likely to trigger Oom,oom is only a representation, the deeper problem may be: memory leaks.

What is a memory leak

Some objects have a limited declaration period, and when the objects are done, we want them to be reclaimed by the garbage collector. But if there is a series of references to this object, it will not be recycled when we expect it to be reclaimed by the garbage collector at the end of the object's life cycle. It also consumes memory, which creates a memory leak. Continuous accumulation, memory is quickly exhausted.

For example: When the activity's OnDestroy () method is called, the activity and the view and related bitmap it involves should be recycled. However, if a background thread holds a reference to the activity, the memory occupied by the activity cannot be recycled, which will eventually cause the memory to run out and cause the app to crash.

PvP Memory Leak

Troubleshooting memory leaks is an all-manual process, which is described in detail in the Raizlabs Wrang Dalvik series article. Here are a few key steps:

    1. Learn about OutOfMemoryError by bugsnag,crashlytics or developer console and other statistical platforms.
    2. Reproduce the problem. To reproduce the problem, the model is important because some problems only occur on specific devices. In order to find a specific model, you need to do everything possible, you may need to buy, to borrow, or even to steal. Of course, in order to determine the recurrence steps, you need to try again and again. Everything was very primitive and rough.
    3. When a memory leak occurs, dump the memory. specifically see here.
    4. Then you need to look through the memory analysis tools such as Mat or Yourkit to find the objects that were supposed to be recycled.
    5. Calculates the shortest strong reference to GC roots for this object.
    6. Determine which app in the application path is not, and then fix it.

It's complicated, isn't it? If there's a class library that can get all of these things done before the oom happens, then you just have to fix them, wouldn't it be nice!!! This is the origin of leakcanary, next we will introduce the use of leakcanary.

Since Google no longer supports the development of Android on Eclipse, it will no longer demonstrate how to use leakcanary on Eclipse, Leakcanary's official website is: https://github.com/square/ Leakcanary, according to the guidance document, use Leakcanary first to introduce, add dependencies in Build.gradle, as follows:

dependencies {debugcompile ' com.squareup.leakcanary:leakcanary-android:1.5 ' releasecompile ' com.squareup.leakcanary:leakcanary-android-no-op:1.5 ' Testcompile ' com.squareup.leakcanary: leakcanary-android-no-op:1.5 '}
After adding leakcanary dependencies in Build.gradle, click the button to sync the project and use Leakcanary. Attentive little partners may notice that we have introduced three modes of dependency, Debugcompile represents a dependent library introduced in debug packaging mode, Releasecompile represents a dependent library introduced in release packaging mode, Testcompile represents a dependent library that was introduced in test packaging mode. In general, different libraries are used in different modes, and the libraries of other schemas are not packaged when the project is packaged. The difference between them will be explained later.

With the introduction of the Leakcanary dependency library, it is then used, based on the guidance document on GitHub, to first initialize the leakcanary in our application as follows:

public class Exampleapplication extends application {    @Override public    void OnCreate () {        super.oncreate ();        if (leakcanary.isinanalyzerprocess (this)) {            //This process was dedicated to leakcanary for the heap analysis.            You should the NOT init your app on this process.            return;        }        Leakcanary.install (this);}    }
The static method Isinanalyserprocess () that calls Leakcanary before initialization is filtered, and if the method returns True, it is returned directly or the install () method that executes leakcanary is initialized. This completes the initialization of the leakcanary, is it very simple? Next we test an example to see how leakcanary detects memory leaks, in the previous article < 12 of the Android source code series > Deep understanding of the leakcanary memory leak detection mechanism from the source point of view (above) Explains the memory leaks that are common in Android development (click here if you haven't seen them yet). We take an example from the previous article: Jump from the current mainactivity page to the Leakactivity page, simulate a long-time task in the Leakactivity page, and then click the Back button to return to the Mainactivity page. Now write leakactivity with the following code:
public class Leakactivity extends Activity {    @Override    protected void onCreate (Bundle savedinstancestate) {        super.oncreate (savedinstancestate);        Setcontentview (r.layout.leak_activity);    }    public void Start (view view) {        new Thread () {            @Override public            void Run () {while                (true) {                    try {
   
    thread.sleep (+);                        LOG.E (Getpackagename (), "leakcanary----->>>>>" + system.currenttimemillis ());                    } catch (Exception e) {                    }}}        }.start ();}    }
   
In Leakactivity, when a button is clicked, a new anonymous internal class thread is launched and a long-time operation is simulated in the thread, and the anonymous inner class defaults to the current mainactivity reference, as explained in the previous article. When the Back button is clicked, the leakactivity should be reclaimed by the system, but the internally initiated thread continues to perform operations, resulting in a memory leak caused by the leakactivity of memory resources that are not released. Then run the program to see the effect:


According to the running effect, after the Leakactivity page is returned to the main page after tapping the button, a prompt will pop up after about 5 seconds, suggesting that in memory leak detection, you will find a notification pop up on the status bar later on. Let's expand this notification to see what's Inside:


Pop-up notification roughly said the package named Com.example.leakcanary under the leakactivity a memory leak, the leaked memory is about 108KB, if you want to see more detailed memory leak information, you can click to view, then we click to see the detailed memory leak Information as follows:


The memory leak reference chain provides a clear and detailed list of the causes of a memory leak, which we can easily locate into a memory leak, and then fix these leak issues. What do you think? Isn't it simple? From then on to the side of the small partners said: With the leakcanary will not be afraid of memory leaks (*^__^*) ... Leakactivity detected a memory leak, according to the repair method of the previous article to modify leakactivity and then run the program will not have notification pop-up.

The use of leakcanary is so simple, if you have not used it is strongly recommended to use once, I believe you can not leave it after the use of it (*^__^*) ... When we introduced the leakcanary, we introduced three different patterns of libraries, there must be a difference between them, after downloading its source code, its structure diagram is as follows:


By reading Leakcanary's code to find out that leakcanary-android is a real memory leak analysis Library, Leakcanary-android-no-op is just an empty shell and nothing is done inside. That is, in the release package when the Leakcanary library will not hit, so do not worry about the introduction of additional methods, only in debug or test mode Leakcanary library will be packaged into the APK.

First look at the Androidmanifest.xml file under Leakcanary-android, as shown below:

<manifest xmlns:android= "http://schemas.android.com/apk/res/android" package= "Com.squareup.leakcanary" > <!--to store the heap dumps and leak analysis results. --<uses-permission android:name= "Android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission androi D:name= "Android.permission.WRITE_EXTERNAL_STORAGE"/> <application> <service android:name = ". Internal.            Heapanalyzerservice "android:enabled=" false "android:process=": Leakcanary "/> <service Android:name= ". Displayleakservice "android:enabled=" false "/> <activity android:name=". Internal. Displayleakactivity "android:enabled=" false "android:icon=" @drawable/leak_canary_icon "an            Droid:label= "@string/leak_canary_display_activity_label" android:taskaffinity= "Com.squareup.leakcanary"    Android:theme= "@style/leak_canary_leakcanary.base" >        <intent-filter> <action android:name= "Android.intent.action.MAIN"/> &lt         Category android:name= "Android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:name= ". Internal.            Requeststoragepermissionactivity "android:enabled=" false "android:icon=" @drawable/leak_canary_icon " Android:label= "@string/leak_canary_storage_permission_activity_label" android:taskaffinity= "Com.squa Reup.leakcanary "Android:theme=" @style/leak_canary_theme.transparent "/> </application></manifes T>
The first request for read and write permissions in the configuration file is to store heap memory information in the file to facilitate analysis of memory leaks in the background. followed by a statement of two service, they were heapanalyzerservice and Displayleakservice,heapanalyzerservice addedandroid:process=": Leakcanary"Properties, which means that Heapanalyzerservice is run in a separate process, and this is done without affecting the app process (such as the effects of stalling the app process), Therefore, when initializing the Leakcanary, the first is to call the Leakcanary static method Isinanalyzerprocess () method to determine whether the current process is the analysis process, if the analysis process does not need to do in the analysis process to do the initialization of the app process, So just go straight back. Finally, two activity,displayleakactivity are shown in the form of a list of memory leaks that have occurred, and clicking on each piece of information in the list goes to the memory leak details page. Requeststoragepermissionactivity know by name that it is used to request storage permissions, It's important to note that both displayleakactivity and Requeststoragepermissionactivity have declaredandroid:taskaffinity="Com.squareup.leakcanary"Properties, which are both said to be running in the new Taskstack, if you are unfamiliar with the taskaffinity attribute, see the article I wrote earlier: Android source series < nine > In-depth understanding of the launchmodel characteristics of activity from the source point of view.

After understanding the relevant configuration of leakcanary, let's look at its related resource files:


Resource files are not explained in detail, what we can do for these resources is that if we do not like these resource files, we can replace them in the project.

Because of space reasons, here is no longer too much analysis of the source of Leakcanary, in the next article I will lead the small partners from the point of view of the source of deep analysis of leakcanary memory leak analysis mechanism, please look forward!!! Finally thanks for watching (*^__^*) ...



"Reference article:"

Https://medium.com/square-corner-blog/leakcanary-detect-all-memory-leaks-875ff8360745#.klentg7g4






Android Source Series < 13 > Deep understanding of Leakcanary's memory leak detection mechanism from the source point of view (medium)

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.