Android Performance Optimization: Ali, Tencent and other knowledge about memory leaks are here!

Recommend collection, otherwise they can not find it! ! !

Foreword

In Android, the phenomenon of memory leaks are common; and a memory leak resulting consequences will make the application Crash In this paper a comprehensive introduction to the nature of memory leaks, reason & solution, ultimately providing some common memory leak analysis tool, hope you like it.

table of Contents

image

1 Introduction

That ML (Memory Leak) refers to the phenomenon in the application program memory, when the memory do not need to use but can not be returned to the program released &

2. The impact of the application

Easy to make the application memory overflow, that OOM memory overflow Description:

Android Performance Optimization: Ali, Tencent and other knowledge about memory leaks are here!

3. The nature of the cause of memory leaks occur

specific description

Android Performance Optimization: Ali, Tencent and other knowledge about memory leaks are here!

  • Special attention from the viewpoint of the mechanism, because the presence of Java garbage collection (the GC), a memory leak should not exist; memory leak occurs because only the outer holding human causes = unintentionally object reference held by such reference lifecycle> referenced's life cycle

4. knowledge base: Android memory management mechanism

4.1 Introduction

Android Performance Optimization: Ali, Tencent and other knowledge about memory leaks are here!

Next, for the recovery process, the object memory allocation, variable & Recycling explain in detail

4.2 for the process of memory strategies . A memory allocation strategy by the ActivityManagerService centrally manage memory allocations for all processes b memory recovery strategy Step 1: Application Framework decision process type Android recovered in the process is hosted; when the process space is tight, it will. process according to low priority - >> high order auto-recovery process Android the process into five priority levels, as follows:

Android Performance Optimization: Ali, Tencent and other knowledge about memory leaks are here!

Step 2: Linux kernel real recovery process ActivityManagerService specific score for all processes (score stored in the variable adj) score to update Linux kernel Linux kernel is done by real memory recovery

Summarize here only processes, which complicate the process, interested readers can research system source code ActivityManagerService.java

4.2 for objects, variables, memory strategies

  • Android for objects, variables, memory strategies with Java
  • = Memory allocation memory management object / variable deallocation +

Below, we'll talk more memory release memory allocation & strategy a. Memory allocation strategy

  • Memory allocation object / variable automatic responsibility of the program
  • There are three kinds: static distribution, dispensing stack, heap & dispensing, respectively, for static variables, local variables & object instance detailed below

Android Performance Optimization: Ali, Tencent and other knowledge about memory leaks are here!

NOTE: memory allocation used to explain an example

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

    // 方法中的局部变量s2、mSample2存放在 栈内存
    // 变量mSample2所指向的对象实例存放在 堆内存
      // 该实例的成员变量s1、mSample1也存放在栈中
    public void method() {        
        int s2 = 0;
        Sample mSample2 = new Sample();
    }
}
    // 变量mSample3所指向的对象实例存放在堆内存
    // 该实例的成员变量s1、mSample1也存放在堆内存中
    Sample mSample3 = new Sample();

b. Memory release strategy

  • Memory release objects / variables are the responsibility of the Java garbage collector (GC) / stack frame
  • Here mainly on the target distribution (that is, heap allocation formula) memory release strategy = Java garbage collector (GC)

Since the static allocation without releasing the stack through an automatic dispensing only stack frame, stack, relatively simple, and therefore not described in detail

  • Java garbage collector (GC) memory release = garbage collection algorithms, including:

Android Performance Optimization: Ali, Tencent and other knowledge about memory leaks are here!

Detailed below

Android Performance Optimization: Ali, Tencent and other knowledge about memory leaks are here!

5. Common causes of memory leaks & Solutions

Common lead to memory leaks main reasons:

  1. Collections
  2. Static member variables modified keywords
  3. Non-static inner classes / anonymous class
  4. Resource object is not closed after use

Below, I will detail why each trigger memory leaks

5.1 collections

  • After adding memory elements, still refer to divulge the reasons collections with a collection element object, causing the object is a collection of elements can not be recycled, resulting in a memory leak example demonstrates:
// 通过 循环申请Object 对象 & 将申请的对象逐个放入到集合List
List<Object> objectList = new ArrayList<>();        
       for (int i = 0; i < 10; i++) {
            Object o = new Object();
            objectList.add(o);
            o = null;
        }
// 虽释放了集合元素引用的本身:o=null)
// 但集合List 仍然引用该对象,故垃圾回收器GC 依然不可回收该对象
  • After the solution collection class to add a collection of elements objects must be removed from the collection after use

Since there are a set number of elements, so the easiest way to empty = & collection object is set to null

 // 释放objectList
        objectList.clear();
        objectList=null;

5.2 Static member variables modified keywords

  • Lifecycle reserve of knowledge to be modified keywords Static member variable of the application life cycle =
  • When the leak reason Ruoshi cited Static keyword modified member variable instances of excessive consumption of resources (such as Context), it is prone to the lifetime of the member variable> citations instance life cycle, when the instances cited to be the end of the life cycle of destruction , due to hold a static variable and can not be recovered, so that memory leak occurs examples to explain:
public class ClassName {
 // 定义1个静态变量
 private static Context mContext;
 //...
// 引用的是Activity的context
 mContext = context; 

// 当Activity需销毁时,由于mContext = 静态 & 生命周期 = 应用程序的生命周期,故 Activity无法被回收,从而出现内存泄露
}
  • solution
  1. Try to avoid Static member variables cited instances of excessive consumption of resources (such as Context)

For reference Context, then try to use the Context Applicaiton

  1. Using weak references (WeakReference) held in place strong reference example

Note: There is a static member variable typical example = singleton

  • Knowledge singleton since reserve static characteristics, the length of the life cycle of the application life cycle =
  • If a leak reason objects do not need to use a single embodiment also holds an object reference to the object, the object will not be properly recovered resulting in a memory leak

Examples of presentations:

// 创建单例时,需传入一个Context
// 若传入的是Activity的Context,此时单例 则持有该Activity的引用
// 由于单例一直持有该Activity的引用(直到整个应用生命周期结束),即使该Activity退出,该Activity的内存也不会被回收
// 特别是一些庞大的Activity,此处非常容易导致OOM

public class SingleInstanceClass {    
    private static SingleInstanceClass instance;    
    private Context mContext;    
    private SingleInstanceClass(Context context) {        
        this.mContext = context; // 传递的是Activity的context
    }  

    public SingleInstanceClass getInstance(Context context) {        
        if (instance == null) {
            instance = new SingleInstanceClass(context);
        }        
        return instance;
    }
}
  • Lifecycle Solutions singleton object referenced application life cycle =

In the example above, the Application should transfer Context, because the life cycle = Application lifecycle of the application

public class SingleInstanceClass {    
    private static SingleInstanceClass instance;    
    private Context mContext;    
    private SingleInstanceClass(Context context) {        
        this.mContext = context.getApplicationContext(); // 传递的是Application 的context
    }    

    public SingleInstanceClass getInstance(Context context) {        
        if (instance == null) {
            instance = new SingleInstanceClass(context);
        }        
        return instance;
    }
}

5.3 Non-static inner classes / anonymous class

  • Reserve non-static inner classes knowledge / default anonymous class holds references to external class; and static inner classes are not
  • Common Case 3 kinds, namely: Examples of nonstatic inner class = static, multi-thread, message passing mechanism (Handler)

5.3.1 Examples of non-static static inner class =

  • If not disclose the cause static inner class instance created = static (application life cycle = life cycle), will hold a reference to the outer class default due to non-static inner classes caused by external class can not be released, eventually leading to memory leaks

That is the outer class held static objects non-static inner class example demonstrates:

// 背景:
   a. 在启动频繁的Activity中,为了避免重复创建相同的数据资源,会在Activity内部创建一个非静态内部类的单例
   b. 每次启动Activity时都会使用该单例的数据

public class TestActivity extends AppCompatActivity {  

    // 非静态内部类的实例的引用
    // 注:设置为静态  
    public static InnerClass innerClass = null; 

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {        
        super.onCreate(savedInstanceState);   

        // 保证非静态内部类的实例只有1个
        if (innerClass == null)
            innerClass = new InnerClass();
    }

    // 非静态内部类的定义    
    private class InnerClass {        
        //...
    }
}

// 造成内存泄露的原因:
    // a. 当TestActivity销毁时,因非静态内部类单例的引用(innerClass)的生命周期 = 应用App的生命周期、持有外部类TestActivity的引用
    // b. 故 TestActivity无法被GC回收,从而导致内存泄漏
  • solution
  1. The non-static inner classes set: static inner class (static inner classes do not hold the default reference the outer class)
  2. The extracted internal class into a single package embodiment
  3. Try to avoid non-static inner classes create instances = static

For use Context, recommended Application of Context

5.3.2 Multithreading: AsyncTask, implement Runnable, Thread class inheritance

  • Use knowledge multithreaded reserve = non-static inner classes / anonymous classes; namely thread class is a non-static inner classes / anonymous class
  • When the worker thread leak reason is processing tasks & external class to be destroyed due to the worker class in holding the external reference will allow external class garbage collector (GC) can not be recycled, resulting in a memory leak

The main use of multi-threading is: AsyncTask, implement Runnable & inherit the same principle before the Thread class 3's memory leaks, mainly in order to inherit the Thread class here as an example

Examples of presentation

/** 
     * 方式1:新建Thread子类(内部类)
     */  
        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);

            // 通过创建的内部类 实现多线程
            new MyThread().start();

        }
        // 自定义的Thread子类
        private class MyThread extends Thread{
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                    Log.d(TAG, "执行了多线程");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

   /** 
     * 方式2:匿名Thread内部类
     */ 
     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);

        // 通过匿名内部类 实现多线程
        new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                    Log.d(TAG, "执行了多线程");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }.start();
    }
}

/** 
  * 分析:内存泄露原因
  */ 
  // 工作线程Thread类属于非静态内部类 / 匿名内部类,运行时默认持有外部类的引用
  // 当工作线程运行时,若外部类MainActivity需销毁
  // 由于此时工作线程类实例持有外部类的引用,将使得外部类无法被垃圾回收器(GC)回收,从而造成 内存泄露
  • Solutions can be seen from the above, there are two key conditions cause memory leaks:
  1. There is reference to the relationship between "working class external thread instance holds references to" the
  2. The life cycle of worker threads instance> External class life cycle, that worker thread is still running while the external class solutions need to destroy the idea = 1 so that the above conditions are not met for either.
// 共有2个解决方案:静态内部类 & 当外部类结束生命周期时,强制结束线程
// 具体描述如下

   /** 
     * 解决方式1:静态内部类
     * 原理:静态内部类 不默认持有外部类的引用,从而使得 “工作线程实例 持有 外部类引用” 的引用关系 不复存在
     * 具体实现:将Thread的子类设置成 静态内部类
     */  
        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);

            // 通过创建的内部类 实现多线程
            new MyThread().start();

        }
        // 分析1:自定义Thread子类
        // 设置为:静态内部类
        private static class MyThread extends Thread{
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                    Log.d(TAG, "执行了多线程");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

   /** 
     * 解决方案2:当外部类结束生命周期时,强制结束线程
     * 原理:使得 工作线程实例的生命周期 与 外部类的生命周期 同步
     * 具体实现:当 外部类(此处以Activity为例) 结束生命周期时(此时系统会调用onDestroy()),强制结束线程(调用stop())
     */ 
     @Override
    protected void onDestroy() {
        super.onDestroy();
        Thread.stop();
        // 外部类Activity生命周期结束时,强制结束线程
    }

5.3.3 message passing mechanism: HandlerAndroid memory leaks: Detailed reasons and solutions Handler memory leak https://www.jianshu.com/p/031515d8a7ca

5.4 resource object is not closed after use

  • Disclose the reasons for the use of resources (such as radio BraodcastReceiver, file stream File, a database cursor Cursor, Bitmap image resources, etc.), if not destroyed Activity timely closure / cancellation of these resources, these resources will not be recovered, resulting in memory leakage
  • Solutions destroyed when the Activity timely closure / cancellation of resources
// 对于 广播BraodcastReceiver:注销注册
unregisterReceiver()

// 对于 文件流File:关闭流
InputStream / OutputStream.close()

// 对于数据库游标cursor:使用后关闭游标
cursor.close()

// 对于 图片资源Bitmap:Android分配给图片的内存只有8M,若1个Bitmap对象占内存较多,当它不再被使用时,应调用recycle()回收此对象的像素所占用的内存;最后再赋为null 
Bitmap.recycle();
Bitmap = null;

// 对于动画(属性动画)
// 将动画设置成无限循环播放repeatCount = “infinite”后
// 在Activity退出时记得停止动画

5.5 Other use

  • In addition to these four common situations, and some daily use can lead to memory leaks
  • Include: Context, WebView, Adapter, detailed below

image

5.6 summarized below, I will summarize the reasons for memory leaks in Android with a map & Solutions

6. The tool-assisted analysis of memory leaks

  • Even fully understand the cause of memory leaks, but inevitably there will be a memory leak or phenomenon
  • The following is a brief analysis of some of the mainstream memory leak tools are
  1. MAT(Memory Analysis Tools)
  2. Heap Viewer
  3. Allocation Tracker
  4. Android Studio 的 Memory Monitor
  5. LeakCanary

6.1 MAT(Memory Analysis Tools)

  • Definition: an Eclipse Java Heap memory analysis tool - >> Download
  • Role: View the current memory usage

By analyzing the memory snapshot of the Java process HPROF analysis, quickly calculate the object in memory footprint size, see which objects can not be garbage collected by & can be viewed intuitively view objects that may cause such results

Specific Use: MAT Use Raiders

6.2 Heap Viewer

Definition: of a Java Heap memory analysis tool Role: View the current memory snapshot

Heap memory can be viewed individually have a total proportion of different types of data & what types of data

Specific Use: Heap Viewer Use Raiders

6.3 Allocation Tracker

Introduction: a trace memory effect analysis tools: tracing the memory allocation information, the specific use in sequence: Allocation Tracker using Raiders

6.4 Memory Monitor

Description: Android Studio comes with a graphical tool to detect memory effect: tracking system / memory usage applications. The core functions are as follows

image

Specific Use: Android Studio to use the Memory Monitor Raiders

6.5 LeakCanary

Description: a square produced Android open source library - >> Download role: to detect memory leaks specific use: https://www.liaohuqiu.net/cn/posts/leak-canary/

7. Summary

This article describes the comprehensive nature of memory leaks, reason & solution, I hope you try to avoid a memory leak in the development

The article is not easy, if you liked this article, or to help you hope a lot of attention Oh thumbs forward. Articles will be continuously updated. Absolutely dry! ! !

Guess you like

Origin blog.51cto.com/14775360/2484779