Summary of several common memory leaks in Android
1、 Background
Recently, in the version iteration of the project, there were some episodes of memory problems, and then I spent some time optimizing the memory size of APP runtime. I hereby make a summary and share with you.
2、 Introduction
In Android program development, when an object no longer needs to be used and should have been recycled, and another object in use holds its reference, so that it cannot be recycled, which leads to that the object that should have been recycled cannot be recycled and stays in heap memory, and memory leakage occurs. What are the effects of memory leaks? It is one of the main causes of application oom. Due to the limited memory allocated by the Android system for each application, when there are many memory leaks in an application, it will inevitably lead to the memory required by the application exceeding the memory limit allocated by the system, resulting in memory overflow and application crash. After understanding the causes and effects of memory leakage, what we need to do is to master the common memory leakage and try to avoid it in future Android program development.
1. Memory leak caused by singleton
Android's singleton mode is very popular with developers, but improper use will also cause memory leakage. Because of the static nature of the singleton, the life cycle of the singleton is as long as that of the application, which means that if an object does not need to be used and the singleton object still holds the reference of the object, the object will not be recycled normally, which leads to memory leakage.
This is an ordinary singleton mode. As we all know, what is the biggest feature of static variables? They are resident in memory, that is, if your app process is not killed, it will always be in memory. When creating this singleton, because a context needs to be passed in, the life cycle of the context is very important: if the context of an activity is passed in: when the activity corresponding to the context exits, the life cycle of the context is as long as that of the activity (the activity inherits from the context indirectly), Therefore, when the current activity exits, its memory will not be recycled, because the singleton object holds the reference of the activity.
Therefore, the correct single example should be this posture:
In this way, no matter what context is passed in, the application context will eventually be used, and the life cycle of the singleton is as long as that of the application, which prevents memory leakage.
2. Memory leakage caused by static instances created by non static inner classes (such as inner classes and anonymous inner classes)
In order to avoid creating the same data resources repeatedly in activities that are frequently started, this method may appear:
In this way, a single instance of a non static internal class is created inside the activity, and the data of the single instance will be used every time the activity is started. In this way, although repeated creation of resources is avoided, this writing method will cause memory leakage, because the non static internal class will hold the reference of the external class by default, and a static instance is created by using the non static internal class, The life cycle of the instance is as long as that of the application, which leads to that the static instance will always hold the reference of the activity, and the memory resources of the activity cannot be recycled normally.
The correct approach is: set the internal class as a static internal class or extract and encapsulate the internal class into a single instance. If you need to use context, please use ApplicationContext.
3. Memory leak caused by handler
Memory leakage caused by the use of handler is the most common problem. Usually, when dealing with network tasks or encapsulating some request callbacks and other APIs, it should be handled with the help of handler. If the code for the use of handler is not standardized, it may cause memory leakage, as shown in the following example:
This way of creating a handler will cause memory leakage. Since mhandler is an instance of the non static anonymous inner class of the handler, it holds a reference to the external class activity. We know that the message queue keeps polling and processing messages in a looper thread. When the activity exits, there are still unprocessed messages or processing messages in the message queue, The message in the message queue holds the reference of the mhandler instance and the mhandler holds the reference of the activity, so the memory resources of the activity cannot be recovered in time, resulting in memory leakage. Therefore, another method is to use soft reference:
Create a static handler internal class, and then use weak references to the objects held by the handler, so that the objects held by the handler can also be recycled during recycling. Although activity leakage is avoided, there may still be messages to be processed in the message queue of the looper thread, so we should remove the messages in the message queue during destroy or stop of the activity, A more accurate approach is as follows:
Use mhandler. Removecallbacksandmessages (null); Yes, remove all messages and all runnable in the message queue. Of course, you can also use mhandler. Removecallbacks(); Or mhandler. Removemessages(); To remove the specified runnable and message.
Of course, it's simpler, or you can do it directly
Pro test, effective.
4. Memory leak caused by thread
Memory leaks caused by threads are also common. The following two examples may be written by everyone:
The above asynchronous task and runnable are both anonymous inner classes, so they both have an implicit reference to the current activity. If the task is not completed before the activity is destroyed, the memory resources of the activity cannot be recycled, resulting in memory leakage. The correct approach is to use static inner classes, as follows:
In this way, the memory resource leakage of the activity is avoided. Of course, the corresponding task asynctask:: cancel() should also be cancelled when the activity is destroyed, so as to avoid wasting resources when the task is executed in the background.
5. Memory leak caused by resource not closed
The use of braodcastreceiver, contentobserver, file, cursor, stream, bitmap and other resources should be closed or logged off in time when the activity is destroyed, otherwise these resources will not be recycled, resulting in memory leakage.
6. For memory leaks caused by WebView, or MapView of Baidu and Gaode maps, please refer to my article
Memory leak caused by WebView: https://www.oudahe.com/p/17103/
The above is the whole content of this article. I hope it will be helpful to your study, and I hope you can support programming tips.