Android Performance Optimization: Hands-on with your full understanding of memory leaks & Solutions

Source: Internet
Author: User
Tags object object

. Brief introduction

i.e. ML (Memory Leak)
The phenomenon that the program does not need to be reused but cannot be released & returned to the program after it has applied for memory
2. Impact on the application

Easy to make an application memory overflow, i.e. OOM
Introduction to Memory Overflow:

3. The intrinsic cause of a memory leak

Specific description

Special attention
From a mechanism perspective, due to the garbage collection mechanism (GC) in Java, there should be no memory leaks, the reason for memory leaks is only external man-made causes = unconscious holding of object references, so that the life cycle of the person holding the reference > The life cycle of the referenced person
4. Reserve Knowledge: Android memory management mechanism

4.1 Introduction

Below, a detailed explanation of memory allocation & recycling for recycling processes, objects, variables

4.2 Memory policy for the process

A. Memory allocation policy

Centrally manage memory allocations for all processes by Activitymanagerservice

B. Memory recovery policy

Step 1:application Framework determines the type of process being recycled
Processes in Android are managed, and when process space is tight, processes are automatically recycled in order of process priority low->> high
Android divides a process into 5 priority levels, as follows:


Step 2:linux The kernel really reclaims the specific process
Activitymanagerservice Scoring for all processes (score is stored in variable adj)
Update ratings to the Linux kernel
True memory reclamation by the Linux kernel
The process is summarized here, which is complicated, and interested readers can study the system source code Activitymanagerservice.java
4.2 Memory policies for objects and variables

Android's memory policy for objects, variables, and Java
Memory Management = memory allocation for objects/variables + memory release
Below, the memory allocation & memory release policy will be explained in detail

A. Memory allocation policy

Memory allocations for objects/variables are automatically handled by the program
There are 3 kinds: Static allocation, stack allocation, & heap allocation, respectively, for static variables, local variables & object instances
Specifically described below

Note: Use 1 examples to explain memory allocation

public class Sample {
int s1 = 0;
Sample MSample1 = new sample ();

Local variables in the method s2, mSample2 stored in the stack memory
The object instance that the variable mSample2 points to is stored in the heap memory
The member variables of the instance, S1, MSample1, are also stored in the stack.
public void Method () {
int s2 = 0;
Sample MSample2 = new sample ();
}
}
The object instance that the variable mSample3 points to is stored in the heap memory
The member variables of the instance, S1, MSample1, are also stored in the stack.
Sample MSample3 = new sample ();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
B. Memory-release policy

Memory deallocation of objects/variables is the responsibility of the Java Garbage collector (GC)/frame stack
The main explanation here is the memory release policy for object allocation (that is, heap allocation) = Java garbage collector (GC)

Because the static allocation does not need to release, the stack allocation only through the frame stack automatically out, into the stack, is simpler, therefore does not describe in detail
The Java Garbage collector (GC) Memory release = garbage collection algorithm, mainly includes:

Garbage Collection algorithm Types

Specifically described below
Summarize

5. Common causes of memory leaks & Solutions

Common causes of memory leaks include:

Collection Class
Static keyword-decorated member variable
Non-static inner class/anonymous class
Resource object is not closed after use
Below, I'll detail each cause of a memory leak

5.1 Collection Class

Memory Leak Reason
When a collection class adds an element, the collection element object is still referenced, causing the collection element object to not be recycled, causing a memory leak

Example Demo

Request an Object object by looping & put the requested objects one by one into the collection list
list<object> objectList = new arraylist<> ();
for (int i = 0; i < i++) {
Object o = new Object ();
Objectlist.add (o);
o = null;
}
Although the collection element reference itself is freed: O=null)
However, the collection list still references the object, so the garbage collector GC still cannot reclaim the object
1
2
3
4
5
6
7
8
9
Solution Solutions
After the collection class has added a collection element object, it must be removed from the collection after it is used
Because there are many elements in the 1 collection, the simplest method = Empty the collection object & set to NULL
Release ObjectList
Objectlist.clear ();
Objectlist=null;
1
2
3
5.2 The Static keyword-decorated member variable

Reserve knowledge
The lifetime of a member variable modified by the Static keyword = The life cycle of the application
Cause of leakage
Shut up a member variable that is modified by the static keyword refers to an instance that consumes too much resources (such as a context), it is easy to see the life cycle of the member variable > Reference instance life cycle, when the reference instance needs to end the life cycle destruction, it will not be recycled because of the static variable holding. Thus a memory leak occurs

Example explanation

public class ClassName {
Define 1 static variables
private static Context Mcontext;
//...
Referring to the context of activity
Mcontext = context;

When activity needs to be destroyed, activity cannot be recycled due to Mcontext = static & lifecycle = Application life cycle, resulting in memory leaks

}
1
2
3
4
5
6
7
8
9
10
Solution Solutions

Try to avoid a Static member variable referencing an instance of a resource that is too expensive (such as Context)

If you need to refer to context, try to use Applicaiton context
Holding instances with weak references (weakreference) instead of strong references

Note: There is a very typical example of a static member variable = Singleton mode

Reserve knowledge
The length of the life cycle of a singleton pattern due to its static characteristics = the life cycle of an application
Cause of leakage
If 1 objects are no longer in use and the Singleton object also holds a reference to the object, then the object will not be recycled properly, causing a memory leak

Example Demo

When creating a singleton, you need to pass in a context
If the context of the activity is passed in, the Singleton holds a reference to the activity
Because the Singleton holds a reference to the activity (until the end of the entire application life cycle), the activity's memory is not recycled even if the activity exits
Especially with some huge activity, it's very easy to cause oom

public class Singleinstanceclass {
private static Singleinstanceclass instance;
Private Context Mcontext;
Private Singleinstanceclass (context context) {
This.mcontext = context; The context of the activity is passed
}

Public Singleinstanceclass getinstance (context context) {
if (instance = = null) {
Instance = new Singleinstanceclass (context);
}
return instance;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Solution Solutions
The life cycle of an object referenced by a singleton pattern = the life cycle of an application
As the above example, the context of the application should be passed, because of the application life cycle = The entire application life cycle
public class Singleinstanceclass {
private static Singleinstanceclass instance;
Private Context Mcontext;
Private Singleinstanceclass (context context) {
This.mcontext = Context.getapplicationcontext (); The context of application is passed on.
}

Public Singleinstanceclass getinstance (context context) {
if (instance = = null) {
Instance = new Singleinstanceclass (context);
}
return instance;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
5.3 Non-static inner class/anonymous class

Reserve knowledge
Non-static inner classes/anonymous classes hold references to external classes by default, while static inner classes do not
Common situations
3: Instances of non-static inner classes = static, multi-threading, message passing mechanism (Handler)
5.3.1 instances of non-static inner classes = static

Cause of leakage
If the instance created by the static inner class = static (its life cycle = the lifetime of the application), the external class cannot be freed due to the non-static inner class holding the reference to the external class by default, resulting in a memory leak

A static object that holds a non-static inner class in an outer class
Example Demo

Background:
A. In active activity, in order to avoid duplicating the creation of the same data resource, a singleton of a non-static inner class is created within the activity
B. The singleton data will be used every time the activity is started

public class Testactivity extends Appcompatactivity {

References to instances of non-static inner classes
Note: set to static
public static Innerclass innerclass = null;

@Override
protected void OnCreate (@Nullable Bundle savedinstancestate) {
Super.oncreate (savedinstancestate);

Ensure that there are only 1 instances of non-static inner classes
if (Innerclass = = null)
Innerclass = new Innerclass ();
}

Definition of non-static inner class
Private class Innerclass {
//...
}
}

Causes of memory leaks:
A. When Testactivity is destroyed, a reference to a non-static inner class singleton (Innerclass) is the lifecycle of the app's life cycle, the reference to the external class testactivity is held
B. Testactivity cannot be recycled by GC, resulting in memory leaks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21st
22
23
24
25
26
27
28
Solution Solutions
Set non-Static inner class to: Static inner Class (Static inner class does not hold references to external classes by default)
The inner class is extracted and encapsulated into a single case.
Try to avoid instances created by non-static inner classes = static
If you need to use context, it is recommended to use the application context
5.3.2 Multi-Threading: Asynctask, implement Runnable interface, inherit thread class

Reserve knowledge
The use of multithreading = Non-static inner class/anonymous class, that is, the thread class is non-static inner class/anonymous class
Cause of leakage
When the work line is impersonating in the processing task & the external class is to be destroyed, the external class cannot be reclaimed by the garbage collector (GC) because the worker instance holds the external class reference, resulting in a memory leak

Multithreading is mainly used: Asynctask, implement runnable interface & Inherit thread class
The first 3 memory leaks are the same principle, here mainly to inherit the thread class as an example explanation
Example Demo

/**
* Method 1: New Thread subclass (inner Class)
*/
public class Mainactivity extends Appcompatactivity {

public static final String TAG = "Carson:";
@Override
public void OnCreate (Bundle savedinstancestate) {
Super.oncreate (savedinstancestate);
Setcontentview (R.layout.activity_main);

Multithreading through the creation of internal classes
New MyThread (). Start (www.famenjie.com);

}
Custom Thread Subclasses
Private class MyThread extends thread{
@Override
public void Run () {
try {
Thread.Sleep (5000);
LOG.D (TAG, "performed multithreading");
} catch (Interruptedexception e) {
E.printstacktrace ();
}
}
}
}

/**
* Way 2: Anonymous thread inner class
*/
public class Mainactivity extends Appcompatactivity {

public static final String TAG = "Carson:";

@Override
public void OnCreate (Bundle savedinstancestate) {
Super.oncreate (savedinstancestate);
Setcontentview (R.layout.activity_main);

Multithreading through anonymous inner classes
New Thread () {
@Override
public void Run () {
try {
Thread.Sleep (5000);
LOG.D (TAG, "performed multithreading");
} catch (Interruptedexception e) {
E.printstacktrace ();
}

}
}.start ();
}
}


/**
* Analysis: Reasons for memory leaks
*/
Worker thread class is a non-static inner class/Anonymous inner class that holds references to external classes by default at run time
When the worker thread is running, if the external class mainactivity needs to be destroyed
Because the worker class instance holds a reference to the external class at this point, the external class cannot be reclaimed by the garbage collector (GC), causing a memory leak
Solution Solutions
As can be seen from the above, there are 2 key conditions that cause memory leaks:
There is a reference relationship where the worker instance holds the external class reference
The life cycle of the worker instance > the life cycle of the external class, that is, the worker thread is still running and the external class is destroyed
The solution of the idea = so that any of the above 1 conditions can not be established.

A total of 2 solutions: Static inner class & force end thread When external class ends life cycle
Specifically described below

/**
* Workaround 1: Static inner class
* Principle: Static inner class does not hold references to external classes by default, so that "worker instance holds external class reference" reference relationship no longer exists
* Specific implementation: Set the subclass of thread to static inner class
*/
public class Mainactivity extends Appcompatactivity {

public static final String TAG = "Carson:";
@Override
public void OnCreate (Bundle savedinstancestate) {
Super.oncreate (savedinstancestate);
Setcontentview (R.layout.activity_main);

Multithreading through the creation of internal classes
New MyThread (). Start ();

}
Analysis 1: Customize the thread subclass
Set to: Static inner class
private static class MyThread extends thread{
@Override
public void Run () {
try {
Thread.Sleep (5000);
LOG.D (TAG, "performed multithreading");
} catch (Interruptedexception e) {
E.printstacktrace ();
}
}
}
}

/**
* Solution 2: Force the end thread when the outer class ends the life cycle
* Principle: Synchronize the life cycle of a worker instance with the life cycle of an external class
* Specific implementation: Forces the end thread (call Stop ()) when an external class (in this case, the activity example) ends the life cycle (the system calls OnDestroy ()))
*/
@Override
protected void OnDestroy (www.huayyule.com) {
Super.ondestroy ();
Thread.stop (www.baqist.cn/);
Force end thread at end of external class activity life cycle
5.3.3 message passing mechanism: Handler

See article: Android memory leak: A detailed explanation of why Handler memory leaks

5.4 Resource object is not closed after use

Cause of leakage
For use of resources (such as broadcast braodcastreceiver, file stream files, cursor cursors, picture resources bitmap, etc.), if these resources are not closed/logged off in time when activity is destroyed, these resources will not be recycled, resulting in memory leaks

Solution Solutions
Close/Log off resources promptly when activity is destroyed

For broadcast braodcastreceiver: Logout registration
Unregisterreceiver (www.dongfan178.com)

For file streams: close stream
Inputstream/outputstream.close (www.huaxinyul.com)

For database cursors cursor: Closing cursors after use
Cursor.close ()

For picture resource bitmap:android the memory allocated to the picture is only 8M, if 1 bitmap objects occupy more memory, when it is no longer used, call recycle () to reclaim the memory occupied by the pixels of this object;
Bitmap.recycle ();
Bitmap = null;

For animations (property animations)
Set the animation to play RepeatCount = "Infinite" after an infinite loop
Remember to stop the animation when activity exits
5.5 Other uses

In addition to the 4 common scenarios mentioned above, there are some daily uses that can lead to memory leaks
Mainly include: Context, WebView, Adapter, specifically described as follows

5.6 Summary

Below, I'll use a graph to summarize the causes & solutions for memory leaks in Android

6. Tools to assist in analyzing memory leaks

Even if you fully understand the causes of memory leaks, there will inevitably be a memory leak phenomenon
The following is a brief introduction to several major tools for analyzing memory leaks, namely
MAT (Memory analysis Tools)
Heap Viewer
Allocation Tracker
Memory Monitor for Android Studio
Leakcanary
6.1 MAT (Memory analysis Tools)

Definition: A Java Heap memory analysis tool for Eclipse->>
Role: View current Memory usage
By analyzing the memory snapshot HPROF analysis of the Java process, you can quickly calculate the size of objects in memory, see which objects cannot be reclaimed by the garbage collector & visually view objects that might result from the view
Specific use: Mat use Raiders
6.2 Heap Viewer

Definition: A Java Heap memory analysis tool
Function: View the current memory snapshot
To see what types of data are in total heap memory & the ratio of various types of data
Specific use: Heap Viewer usage Tips
6.3 Allocation Tracker

Introduction: A Memory trace analysis tool
Function: Track memory allocation information in sequential order
Specific use: Allocation Tracker use Raiders
6.4 Memory Monitor

Introduction: An Android Studio comes with a graphical detection memory tool
Function: Tracks the memory usage of the system/application. The core functions are as follows

Specific use: Memory monitor using Android Studio tips

6.5 Leakcanary

Introduction: A square-produced Android Open Source Library->>
Role: Detecting memory leaks
Specific use: https:/wwww.dashuju178.com/cn/posts/leak-canary/
7. Summary

This article comprehensively introduces the nature, cause & solution of memory leak, I hope you avoid memory leak when developing.

Next article I will explain the knowledge of Android performance optimization, interested can continue to focus on Carson_ho's Android development notes
Please help the top/comment to praise! Because your encouragement is my biggest motive of writing!

Android Performance Optimization: Hands-on with your full understanding of memory leaks & Solutions

Contact Us

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.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.