This article only describes the basic concepts related to memory optimization and the basic tools and open source framework used, and finally introduces several memory leaks that often occur in Android development and solutions;
This paper only serves as a primer. To improve memory optimization ability, we need to continue to practice in the project to summarize experience. I will continue to summarize and update this article when I encounter problems related to memory optimization in the future projects;
First, memory optimization basis
Android assigns each App a VM to run on, so that if the App crashes, the system won’t be affected. The system allocates a certain memory size to the VM, and the memory size that App can apply for cannot exceed this hard logical limit. Even if the physical memory is surplus, if the application exceeds the maximum memory of the VM, memory overflow crash will occur.
Memory Indicator Concept
Item | The full name | meaning | equivalent |
---|---|---|---|
USS | Unique Set Size | Physical memory | Process-exclusive memory |
PSS | Proportional Set Size | Physical memory | PSS= USS+ includes shared libraries proportionally |
RSS | Resident Set Size | Physical memory | RSS= USS+ contains shared libraries |
VSS | Virtual Set Size | Virtual memory | VSS= RSS+ No actual physical memory allocated |
Android low memory process killing mechanism
Anroid specifies five default reclaim priorities based on the components running in the process and their state:
- Empty Process
- Background process
- Service process
- Visible process
- Foreground process
When the system needs to reclaim memory, empty processes will be reclaimed first, then background processes, and so on, and finally foreground processes will be reclaimed (normally foreground processes are the processes that interact with users, if even foreground processes need to be reclaimed, then the system is almost unavailable).
Introduction to Android memory analysis commands
Dumpsys meminfo is used to print memory usage details
Procrank gets a ranking of memory usage for all processes, sorted by Pss size. The procrank command outputs more detailed VSS/RSS/PSS/USS memory metrics than the dumpsys meminfo command.
Cat /proc/meminfo To view more detailed memory information
Free Displays the available memory. The default unit is KB. This command is simple and lightweight, and focuses on checking the remaining memory. Data is obtained from /proc/meminfo.
You can view the memory information in the virtual address area by running the showmap command
Vmstat can view not only the memory status, but also the process running queue, system switchover, and CPU time ratio. In addition, this command is output periodically and dynamically.
Third, memory optimization tools
Android Studio’s built-in Profiler performance Profiler
For detailed use, please refer to the official website
Developer. The android. Google. Cn/studio/initial…
Open source framework detects memory leak LeakCanary
The principle is actually using GCRoot reachability algorithm analysis
4. Common scenarios of Android memory leakage and solutions
1. The resource object is not closed
When a resource object is no longer in use, its close() function should be called immediately, then set to NULL. For example, if resources such as Bitmap are not closed, memory leaks can occur and should be closed when the Activity is destroyed.
2. The registered object is not deregistered
For example, memory leaks caused by BraodcastReceiver and EventBus not being logged out should be logged out as soon as the Activity is destroyed.
Class static variables hold big data objects
Avoid using static variables to store data, especially big data objects, and use databases instead.
4. Memory leaks caused by singletons
Use the Application Context first. If you want to use the Activity Context, you can use a weak reference to encapsulate it when passing in the Context. Then, you can retrieve the weak reference from the used Context.
Static instances of non-static inner classes
The lifetime of the instance is as long as that of the application, which causes the static instance to hold a reference to the Activity, and the Activity’s memory resources cannot be recycled properly. At this point, we can set the inner class as a static inner class or extract the inner class and encapsulate it as a singleton. If we want to use Context, use the Application Context. If we want to use the Activity Context, remember to empty it so that the GC can recycle it. Otherwise you still get a memory leak.
6, Handler temporary memory leak
A Message is stored in a MessageQueue. There is a target in the Message, which is a reference to the Handler. If the Message is in the Queue for too long, the Handler cannot be reclaimed. If the Handler is non-static, the Activity or Service will not be collected. And the Message queue is constantly polling for messages in a Looper thread. When the Activity exits, there are unprocessed or processed messages in the Message queue, and Message in the Message queue holds references to Handler instances, which in turn hold references to the Activity. As a result, the Activity’s memory resources cannot be reclaimed in time, causing a memory leak. The solution is as follows:
- 1. Use a static Handler inner class, and then use weak references to the object that the Handler holds (typically an Activity) so that when it is recycled, it can also reclaim the object that the Handler holds.
- When the Activity is destroyed or stopped, messages should be removed from the message queue to prevent pending messages from being processed in the message queue of the Looper thread.
It should be noted that AsyncTask is also a Handler mechanism, which also has the risk of memory leakage, but it is usually temporary. For memory leaks such as AsyncTask or thread leaks, we can separate AsyncTask and Runnable classes or use static inner classes.
7, the WebView
Webviews have a memory leak problem. Once a WebView is used in an application, the memory will not be released. We can start an independent process for WebView and use AIDL to communicate with the main process of the application. The process where WebView is located can be destroyed at an appropriate time according to the needs of the business to achieve the purpose of normal memory release.