In the last article Android memory optimization (a) : Java memory area has generally introduced the memory distribution in Java, this article mainly talks about the causes of memory leaks, the harm of memory leaks, memory leak one-click analysis and location, and common memory leaks in the code.
High energy ahead, under 18 years old please avoid!! Big Mimi: Memory leak is caused by objects occupying the manger!! It’s important to talk about how garbage collection works in Android. Android uses a Mark-sweep algorithm for garbage collection. The garbage collector iterates through all objects to see which objects can be collected to free up memory. This process is called “Mark” and requires all threads except The garbage collection thread to Stop. This phenomenon is called “Stop The World” in garbage collection algorithms. This causes our program to stall, but usually this time is tens of milliseconds, I do not feel at all. After Mark is done, it frees up memory space, a process called Sweep.
All of this looks great, but there is a memory leak, so it should be mentioned that not all objects are telonsu, pooh, not all objects can be recycled, like the one below.
- Principles of garbage collection:Objects referenced directly and indirectly by global variables (static), stack variables, registers, etc., cannot be reclaimed.
So, if an object is being referenced by other objects even after it’s been used, it can’t be recycled, resulting in a waste of memory.Let the other objects have no shit. Memory leaks are caused by objects not being collected by GC!
Memory leaks are usually difficult to detect without a tool, because Java does not report memory leaks, so minor memory leaks appear to be the same as normal ones.
- 2.1 Memory Leak The difference between memory Overflow (OOM) and memory Leak is: ** quantitative change and qualitative change. ** One or two memory leaks appear to be fine, but quantitative changes can lead to qualitative changes, memory leaks will explode, is reported OOM exception, application directly crash, even the opportunity to explain.
- 2.2 The size of heap memory is fixed, and The available memory will decrease after The occurrence of memory leak, which will increase The frequency of garbage collection. As mentioned above, during The Mark stage of garbage collection, there will be a phenomenon of “Stop The World”, that is, threads other than garbage collection threads will Stop. Frequent garbage collection jams are clearly felt.
- 2.3 When the application is running in the background, the memory usage is large, and the probability of the process being killed by the system is large.
Memory leak analysis, you must use tools, fortunately, various gods have provided us with a lot of powerful memory analysis tools, I will only talk about the most convenient. There are several packages to choose from: ####3.1 Package 1 :Studio Heap Viewer Want to know if your application is leaking memory? Seriously, just for a minute.
-
3.1.1 Open Studio and attach your application to Android Monitor (1)->Monitors(2)->Memory The downward arrow icon (4) is used to view heap allocation, and the last icon, allocation Tracker, is used to track memory allocation.
-
3.1.2 Let me explain how I use it. In the application, I jump from Activity1 to Activity2 and then back to activity1. This is to analyze whether Activity2 has memory leaks. Now it’s time for the real thing.
-
3.1.3 Click the car icon (3) to manually collect garbage, so as to more accurately determine whether There is memory leak in Activity2. Finally, click the down arrow icon (4), Studio will automatically generate hprof file and display it in the Studio interface.
-
3.1.4 This is the memory analysis file. Click Analyzer Tasks(5) to ask Studio to automatically analyze if there is a memory leak.
-
3.1.5 Check the Detect Leaked Activities(6) and finally run (7) to get the analysis results
-
3.1.6 Activity2 has a memory leak (8). In the lower left corner is the reference tree (9). The reference tree is used to locate the memory leak.
####3.2 Package 2: Heap Viewer + MAT Yes, a memory leak has been found, however there are other options, which must be assisted by other tools.
MAT(Memory Analyzer) Memory analysis tool
- 3.2.1MAT downloadEnter the DOWNLOAD official website, my computer is 64-bit, so CHOOSE Windows(X86_64), the entire DOWNLOAD and installation process is the same as ordinary software, enter a new page and click DOWNLOAD
Click here to download and use it
- 3.2.2 Import of hprof file, the process of obtaining this file is basically the same as the process of finding memory leaks. It is obtained by Studio Heap as described above, but it needs to be converted before importing the file, because MAT cannot be used directly and conversion is not troublesome, Studio has helped you simplify the process. One click export conversion file, please look over
- 3.2.3 Open the conversion files of Hprof by MAT. Histogram and Dominator Tree are commonly used, and comparative analysis of the two files of Histogram is especially required for the analysis of memory leaks, that is, obtaining the hPROF conversion files before and after memory leaks
- 3.2.3 Title Bar Window->Navigator History, open the Navigator History panel, and then click to open Histogram,! [](http://upload-images.jianshu.io/upload_images/4821599-205d2c4bd313d070.png? imageMogr2/auto-orient/strip%7! [Uploading memory 8_883765.png..] cimageview2/2 / W /1240)
- 3.2.4 Right-click histogram and add both histogram results from both analysis files to Compare Basket by clicking on the upper-right corner! The icon will generate a comparison file
- 3.2.5 This is the final generated comparison file. You can also choose the comparison method by yourself. Different comparison methods are provided in the red circle, so that the differences can be seen intuitively.
####3.3 Package three: Leakcanary Square’s open source memory leak analysis framework is incredibly useful and easy to configure
- 3.3.1 Suggested in app
build.gradle
Add the following dependencies under the file
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'} ` ` ` - 3.3.2 rainfall distribution on 10-12 in your ` ` ` Application ` ` ` of ` ` ` onCreate () ` ` ` method for initializationCopy the code
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… }}
-3.3.3 Then, there is no then, after compiling and running your project, there will be an additional component after the project is successfully installed, which will show the specific memory leak path. ! [](http://upload-images.jianshu.io/upload_images/4821599-68cfb470f5cf3bb0.png? ImageMogr2 /auto-orient/strip% 7cImageView2/2 / W /1240) -3.3.4 Through this leak path, the cause of the corresponding memory leak is analyzed. You can also locate the memory leak through the output log. ! [](http://upload-images.jianshu.io/upload_images/4821599-cd2b7b28aed9223e.png? ImageMogr2 / auto - received/strip % 7 cimageview2/2 / w / 1240) > note: I have finished talking about the three packages here. As for the package MAT, I just talk about the basic usage, which is enough in fact. How to say, it is troublesome to use MAT, so I seldom use it myself. 1. Package 3 is the most convenient to use, once and for all. The speed of parsing hprof is a little slow, but because the background automatically parses it, it basically doesn't matter. 2. As soon as the package is used the fastest, you will know whether there is memory leakage after switching the page in minutes, but you need to manually operate every time; 3. Package 3 is the most troublesome and time-consuming, but the automatic analysis tool cannot guarantee to find out all the memory leaks. At this time, MAT is required to assist the analysis.Common causes of memory leaks in codeMemory leaks in code are mostly caused by non-compliance with the activity lifecycle. -4.1 Singleton Mode (Static Activity) : Define a static variable in your Activity that references the Activity. Because static variables have the same lifetime as the app, even if the Activity is destroyed, the Activity object is still held by the static variable until the app is destroyed. This is where the singleton pattern is most vulnerable to leaks. If a static singleton holds a reference to an activity object, it cannot be recycled properly, leading to a memory leak. The solution is to use the Application Context instead of the activity Context;Copy the code
/ * *
- Public class SingletonClass{private static SingletonClass instance; private Context context; public static SingletonClass getInstance(Context context){ synchronized(SingletonClass.class){ if(instance==null){ instance=new SingletonClass(Context context); } } return instance; } private SingletonClass(Context context){ this.context = context; // Passing in the activity context causes a memory leak.
-4.2 Static View: When a View is added to the interface, it holds a strong reference to the context, which is our activity. If we refer to the View through a static member variable, we refer directly to the activity, and we leak it;Copy the code
private static View view; view = findViewById(R.id.sv_button);
-4.3 Non-static inner Classes: We all know that inner classes can refer to members of an external class. This is one of the advantages of inner classes, but it is this advantage that can cause activity memory leaks, because non-static inner classes hold references to external classes by default. If we create an object of an inner class and hold it through a static variable, we will cause a memory leak;Copy the code
private static InnerClass inner = new InnerClass();
class InnerClass {
}
Copy the code
-4.4 Anonymous Inner Classes: Anonymous classes also hold references to the objects that define them. If an anonymous AsyncTask object is defined within an activity, memory leaks may occur. Because the AsyncTask may still be running after the activity is destroyed, the activity can only be reclaimed after the AsyncTask is finished.Copy the code
new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void… params) { while(true); } }.execute();
-4.5 Handler+Runnable: Defining an anonymous Runnable object and submitting it to the Handler may also cause the activity to leak. The Runnable object refers to the activity object that defines it, and it is submitted to the Handler's MessageQueue. If it has not been processed by the time the Activity is destroyed, it will cause a memory leak.Copy the code
new Handler() { @Override public void handleMessage(Message message) { super.handleMessage(message); } }.postDelayed(new Runnable() { @Override public void run() { while(true); }}, 1000);
-4.6 Thread: The reason is similar to 4.5. Although the task is executed in a separate Thread, the Thread still holds external objects by default. The reference held by the Thread will not be released until the task is completed.Copy the code
new Thread() { @Override public void run() { while(true); } }.start();
-4.7 Resources are not closed: If you are using resources such as BraodcastReceiver, ContentObserver, File, Cursor, Stream, Bitmap, etc., you should shut down or log out when your Activity is destroyed; otherwise, these resources will not be reclaimed, causing a memory leak. -4.8 Collection container: When we do cache, we will use some data structures to store some data. When we do not need it, we need to clean it in time, otherwise it will snowball into bigger and bigger, and it is difficult to avoid leakage. Word-wrap: break-word! Important; "> < p style =" max-width: 100%; "The bank of thousands of feet, with ants hole collapse; A hundred feet of room, with a sudden gap of smoke burn." So I recommend Package Three Leakcanary to keep your entire development process monitored for memory leaks.Copy the code