The introduction
Still worried about not being able to use MAT? Still looking for the source of the memory leak with the Hprof graph parsed by MAT? Give up the struggle, boy. In the Android Studio era, we use LeakCanary, a dumb-ass memory leak detection tool.
Introduction to the
LeakCanary is from Square, the famous company behind OkHttp, Retrofit and Picasso. LeakCanary allows your App to automatically pop alert when a memory leak occurs while in Debug mode, but does nothing when in Release mode.
The website links
LeakCanary A Memory leak Detection library for Android and Java. If you are a good English reader, you don’t need to look further. The home page has everything you need.
Rapid integration
Step 1: Add the following dependencies to build.gradle:
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'
}Copy the code
Step 2: Add the following code to your own Application (suppose named ExampleApplication) :
public class ExampleApplication extends Application {
@Override public void onCreate() {
super.onCreate();
if (LeakCanary.isInAnalyzerProcess(this)) {
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
return;
}
LeakCanary.install(this);
// Normal app init code...}}Copy the code
In this case, you can actually detect a memory leak in your Activity. Run your App in Debug mode and you’ll see a Leaks icon followed by your App icon, as shown below. If you’re running in Release mode, you don’t have that icon.
Test using
Pretend you’re a tester, and you start clicking on the App to test it. Then you’re lucky enough to see a popup like this, as shown below.
You are curious and click on the icon in the middle of the popup box, which brings up the icon of your App in the top left corner of the screen. Pull down and click on that icon, or click on the LeakCanary icon (the one right behind your App icon) on the desktop, and you see the image below. Click the + sign to expand, click the – sign to fold up.
Memory leaks usually occur when objects with long life cycles, directly or indirectly, hold strong references to objects with short life cycles, causing the objects with short life cycles to fail to be released in time. The diagram above is silly enough. The first line represents the object with the long life cycle, which is the AliPayModel class. The second line shows what kind of reference the one with the long life holds, in this case mActivity; The third line represents the object with the short life cycle, in this case SelectPayTypeActivity. In SelectPayTypeActivity, the XXX() method in the singleton is called as alipayModel.getInstance (this).xxx (). So AliPayModel passed the mActivity hold SelectPayTypeActivity. This reference. SelectPayTypeActivity is supposed to be released when the user exits the page and enters another Activity (especially if the other Activity is at a deeper level), but the singleton life cycle lasts throughout the App, The AliPayModel keeps referencing SelectPayTypeActivity, which causes the SelectPayTypeActivity to fail to be released in time, causing a memory leak.
public class AliPayModel extends BasePayModel {
private Activity mActivity;
private AliPayModel() {}
private static AliPayModel instance = new AliPayModel();
public static AliPayModel getInstance(Activity tag) {
instance.mActivity = tag;
return instance;
}Copy the code
The cause was found, and a solution was in sight. Either the AliPayModel business class should not be defined as a singleton, or the mActivity should change from a strong reference to a soft or weak reference. The distinction between Strong, soft, weak, and virtual Java references is beyond the scope of this article.
Memory leaks found in open source components
Using the above methods, you can detect a variety of memory leaks, including WebView leaks, resource leaks, non-static anonymous inner class leaks, Handler leaks, and so on. Take a look at the picture below. Every time you select an image or upload your avatar, it will cause a memory leak of 0.96 MB!
And with a steed,The culprit is to define an Activity as static. It means you don’t really understand this kind of god code. The most impressive thing is that it has more than 2600 stars! In the Issues of this project, a lot of people reflect the memory occupation, easy OOM, card, etc., but no one from the technical level to find and analyze the reason, let alone to read the source code, are directly taken to use!
conclusion
With a simple configuration, we found memory leaking code in our own project very quickly, and we stumbled upon serious memory leaks in open source components. When asked about the memory leak detection tool in your next interview, don’t just habitually say MAT. But is that all there is to LeakCanary? Far from it! Besides activities, what other objects can we monitor? Which activities can we not monitor (how to add exceptions)? How do I customize my LeakCanary? Every foreign awesome project on Github will introduce its use, configuration, implementation principle and so on in README or Wiki, or attach the external link of blog and website. If you’re not used to getting first-hand information on LeakCanary, the follow-up to this article, Guide to LeakCanary (2), is something to look forward to!