<span id="Label3"></p>Objective<p><p>Are you troubled by a probabilistic OOM? sometimes, OOM is like a ghost, lingering, but really want to pull it out, and catch it. Maybe it's time to use leakcanary to diagnose it. It's an open source library for checking for memory leaks under Android <span id="14_nwp">, and this article focuses on its usage, <span id="15_nwp">architecture, and how it's implemented behind it. </span></span></p></p><p><p>Square has an article about the reasons for developing this library. In one of their payment processes, users ' signatures need to be used, and they use Bitmap to draw signatures directly, Bitmap the same size as the screen Resolution. The problem is that, when trying to create this Bitmap object, the probabilistic OOM comes as a ghost. They tried a few ways:</p></p> <ul> <ul> <li>Use <code>Bitmap.Config.ALPHA_8</code> to save memory</li> <li>Catch <code>OutOfMemoryError</code> exception, call GC to clean up memory, and then retry several times</li> </ul> </ul><p><p>ultimately, none of this works. Eventually they found that they had gone too far in the wrong direction. When there is a memory leak, there is less available memory, and this time OOM can occur anywhere, especially when trying to create some large memory objects, such as Bitmap.</p></p><p><p>In our previous article, "Android memory and performance," we described how to use MAT to analyze memory leaks. The core steps outlined are:</p></p> <ul> <ul> <li>Export the HPROF file after an OOM or a possible memory leak has occurred</li> <li>Using MAT to combine code analysis to find some reference exceptions, such as which objects should have been recycled, but still in the system heap, then it is a memory leak</li> </ul> </ul><p><p>If there is a tool that can automate these things, and even report a memory leak to you before an OOM happens, what a wonderful thing it is. Leakcanary is used to do this thing. If a memory leak occurs while testing your App, a notification will tell you on the status bar. Logcat will also have a corresponding log to inform YOU.</p></p><p><p>Inspired</p></p><p><p>There are several interesting inspirations behind Leakcanary's Emergence. One is that companies like Square will be troubled by the problem of OOM, the second is that they will make mistakes and try several methods that do not work; they finally solved the problem in an elegant way, and <span id="13_nwp">let everyone share their work through the open source Library. </span></p></p>Usage monitoring Activity leaks<p><p>We often use activity as a Context object, and the activity is referenced by various objects on different occasions. therefore, Activity leaks are one of the important memory leaks that need to be checked.</p></p><pre><pre><strong></strong> public <strong>class</strong> <strong>extends</strong> Application {public <strong></strong><strong>static</strong> refwatcher getrefwatcher (context Context) { exampleapplication application = (exampleapplication) Context.getapplicationcontext (); <strong>return</strong> <span id="12_nwp">application.refwatcher; } <strong>Private</strong> Refwatcher refwatcher; <strong></strong> public <strong>void</strong> onCreate () { <strong>Super</strong>. OnCreate (); Refwatcher = Leakcanary.install (<strong></strong>this);} }</span></pre></pre><p><p><code>LeakCanary.install()</code>Returns a well-configured <code>RefWatcher</code> instance. It is installed at the same time <code>ActivityRefWatcher</code> to <span id="11_nwp">monitor Activity leaks. That is, <code>Activity.onDestroy()</code> if the Activity is not destroyed after being called, Logcat will print out the following information to tell you that the memory leak has Occurred. </span></p></p><pre><pre> * Com.example.leakcanary.MainActivity has leaked: <span id="10_nwp">java.lang.thread.<java local> (named ' Asynctask #1 ') * References com.example.leakcanary.mainactivity$2.this$0 (anonymous class extends Android.os.AsyncTask) * Leaks com.example.leakcanary.MainActivity Instance * Reference key:c4d32914-618d-4caf-993b-4b835c255873 * device:genymotion generic Google Galaxy nexus-4.2.2-api 17-720x1280 vbox86p * Android version:4.2.2 Api:17 <c8 />* durations:watch=5100ms, gc=104ms, Heap dump=82ms, analysis=3008ms</span></pre></pre><p><p>Notes</p></p><p><p>Leakcanary automatic detection of Activity leaks only supports Android ICS above Version. Because <code>Application.registerActivityLifecycleCallbacks()</code> it was introduced in API 14. If you want to monitor Activity leaks before ICS, you can overload the <code>Activity.onDestroy()</code> methods and invoke them in this method <code>RefWatcher.watch(this)</code> .</p></p>Monitor Fragment leaks<pre><pre><strong></strong> public <strong>Abstract</strong> <strong>class</strong> <strong>extends</strong> Fragment { @Override public <strong></strong><strong>void</strong> OnDestroy () { <strong>Super</strong>. OnDestroy (); Refwatcher refwatcher = exampleapplication.getrefwatcher (getactivity ()); Refwatcher.watch (<strong></strong>this);} }</pre></pre><p><p>When <code>Fragment.onDestroy()</code> called, If the fragment instance is not destroyed, the corresponding leak information is seen from the Logcat.</p></p>Monitor other leaks<pre><pre> ... Refwatcher refwatcher = exampleapplication.getrefwatcher (getactivity ()); Refwatcher.watch (someobjneedgced);</pre></pre><p><p>When <code>someObjNeedGced</code> it is still in memory, you will see a hint of the memory leak in the Logcat.</p></p>Integrated Leakcanary Library<pre><pre>Dependencies { debugcompile ' com.squareup.leakcanary:leakcanary-android:1.3 ' releasecompile ' com.squareup.leakcanary:leakcanary-android-no-op:1.3 '}</pre></pre><p><p>On the debug version, integrate the Leakcanary library and perform memory leak monitoring, and on the release version, integrate a non-operational WR<span id="9_nwp">apper, which has no effect on program Performance. </span></p></p>Principle Leakcanary Flowchart<p><p></p></p><p><p>The leakcanary mechanism is as follows:</p></p> <ol> <ol> <li><code>RefWatcher.watch()</code><span id="3_nwp">creates a <code>KeyedWeakReference</code> weak reference object with a monitoring object</span></li> <li>In <code>AndroidWatchExecutor</code> the background thread, to check that the weak reference has been cleared and, if not cleared, to perform a GC</li> <li>If the weak reference object is still not cleared, indicating a memory leak, the system exports the Hprof file, saved in the App's file system directory</li> <li><code>HeapAnalyzerService</code>Starts a separate process that is used <code>HeapAnalyzer</code> to parse the hprof file. It uses another <span id="2_nwp">open source library, HAHA. </span></li> <li><code>HeapAnalyzer</code><code>KeyedWeakReference</code>find internal leaks by finding weak reference objects</li> <li><code>HeapAnalyzer</code>Computes the <code>KeyedWeakReference</code> shortest strong reference path to the referenced object, parses the memory leak, and <span id="1_nwp">constructs an object reference Chain. </span></li> <li>Memory leak information is sent back <code>DisplayLeakService</code> , it is <span id="0_nwp">a service running in the app Process. The memory leak information is then displayed in the device notification bar. </span></li> </ol> </ol>A few interesting code<p><p>How to export hprof files</p></p><pre><pre><strong>New</strong> File ("heapdump.hprof");D ebug.dumphprofdata (heapdumpfile.getabsolutepath ());</pre></pre><p><p>You can refer to Androidheapdumper. <span id="8_nwp">Java Code. </span></p></p><p><p>How to analyze Hprof files</p></p><p><p>This is a relatively big topic, interested in another <span id="7_nwp">Open Source Library HAHA, its ancestors are MAT. </span></p></p><p><p>How to use Handlerthread</p></p><p><p>You can refer to the code for androidwatchexecutor.java, especially regarding the use of Handler, Loop.</p></p><p><p>How to know that a variable has been recycled by GC</p></p><p><p>You can refer to the Refwatcher.java <code>ensureGone()</code> <span id="6_nwp">Function. The most important is the use <code>WeakReference</code> and <code>ReferenceQueue</code> Mechanism. Simply put, when the object referenced by the weak reference is <code>WeakReference</code> recycled, the object is <code>WeakReference</code> added to the <code>ReferenceQueue</code> queue, and we can get an instance of the <code>poll()</code> object that is being reclaimed by its method <code>WeakReference</code> , and then know whether the object that needs to be <span id="5_nwp">monitored is recycled. </span></span></p></p>About memory leaks<p><p>Memory leaks can be easily discovered, such as when the Cursor is not closed, for example, in a <code>Activity.onResume()</code> register to listen for an event, but forgetting unregister in it, and <code>Activity.onPause()</code> memory leaks can be difficult to find, such as the Leakcanary sample code, implicitly referenced, and And only occurs when the screen is Rotated. There are also more difficult to find, even helpless memory leaks, such as bugs in the Android SDK itself causing memory leaks. Androidexcludedrefs. In java, some of the <span id="4_nwp">known versions of AOSP are documented with memory leaks in their OEM implementations. </span></p></p>Recommended in this issue<p><p>Recommend a drawing tool planuml, its biggest feature is to use the script to DRAW. The biggest difference between it and STARUML is that the former is a drawing tool, similar to Microsoft's visio, and supports script drawing, which is a modeling tool. This is the official document of Planuml. It also supports a bunch of extensions, such as Sublime Text. The flowchart of this paper is to draw with Planuml.</p></p><p><p>Use Leakcanary to check for Android memory leaks</p></p></span>
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.