Summary of Android memory leaks and performance optimization tips

       When we develop Android applications, performance optimization is a very important aspect. On the one hand, optimization can improve the response speed of the application, reduce the lag rate and improve the smoothness of the application, thereby improving the user experience; on the other hand, optimization can also reduce the resource usage of the application, improve the stability and security of the application, and reduce the application cost. probability of being killed, thereby improving user satisfaction and retention.

      However, for many developers, Android performance optimization is often a difficult issue. Since there are many types of Android devices with different hardware configurations, optimization methods and strategies are also different. At the same time, the development cycle of Android applications is long and often requires continuous iteration and updates, so optimization also needs to be continued and optimized.

        Learning the knowledge and skills of Android performance optimization is one of the essential skills for every Android developer. By mastering the basic principles and methods of Android performance optimization, we can have a deeper understanding of the working mechanism of Android devices and understand the performance bottlenecks of applications, so as to adopt effective optimization strategies and measures to improve application performance and stability and improve user satisfaction. and retention rates.


       This article introduces the basic principles, optimization strategies and practical techniques of Android performance optimization to help developers better understand the working principle of Android devices and master the basic methods and techniques of Android performance optimization, thereby improving the performance and stability of applications and providing users with Provides a silkier experience.

There are a wide range of Android performance optimization issues. Here are some of the common ones:

  1. Memory leaks: Memory leaks occur when an application improperly manages memory, causing excessive memory usage or even causing the application to crash.

  2. Layout optimization: Layout is one of the most common performance bottlenecks in applications, because an overly complex layout can cause the application to respond slowly or freeze.

  3. Image optimization: Images are one of the most memory-intensive resources in an application, so they must be used with caution and properly compressed and cached to ensure application performance.

  4. Network request optimization: Network requests can take up a lot of time and resources in an application, so they must be optimized to reduce the number of requests and increase response speed.

  5. Database optimization: When an application requires heavy access to the database, it can cause performance issues. Application performance can be improved by optimizing database design and using appropriate database caching.

  6. Multithreading Optimization: Multithreading can improve application performance, but if they are used incorrectly, they can lead to deadlocks, thread contention, and other problems.

  7. Memory Optimization: Memory is one of the important factors in application performance. You can improve application performance by promptly releasing memory that is no longer needed and avoiding unnecessary memory allocations.

  8. Code Optimization: Optimizing code structures and algorithms can improve application performance. For example, use faster and more efficient data structures and algorithms to improve application responsiveness.

  9. Security Optimization: Security issues can also negatively impact the performance of your application. You can improve application security and performance by avoiding unsafe coding practices and using encryption to protect your data.

Android performance optimization boils down to memory issues, and memory-level optimization is not only the conventional optimization items described in the description, but can also further optimize the number of disk reads and writes, disk page data synchronization, etc.

1. Memory leak

A memory leak refers to the inability of an application to correctly release memory resources that are no longer used during operation, resulting in a continuous increase in memory usage and eventually causing the application to crash or run slowly.

The principle of memory leak

The principle of Android memory leak means that when an application uses memory, due to programming problems or errors, it cannot release the memory that is no longer used, which ultimately leads to insufficient memory in the system, affecting the stability and performance of the system.


Here are some common causes that can cause Android memory leaks:

Object reference not released

When objects are created, if they are not released correctly, these objects will occupy memory until the application exits. For example, when an Activity is destroyed, if it still holds references to other objects, then these objects cannot be recycled by the garbage collector, resulting in a memory leak.

If there is a memory leak, then the objects in these memories will be referenced and cannot be recycled by the garbage collection mechanism. At this time, we need to use GCRoot to identify the memory leaked objects and references.

GCRoot is the root node in the garbage collection mechanism. The root node includes the virtual machine stack, local method stack, class static attribute references in the method area, active threads, etc. These objects are regarded as "living objects" by the garbage collection mechanism and will not Be recycled.


When the garbage collection mechanism is executed, it will start from GCRoot, traverse all object references, and mark all living objects. Unmarked objects are garbage objects and will be recycled.


When there is a memory leak, the garbage collection mechanism cannot recycle some objects that are no longer used. These objects are still referenced, forming some reference chains from GCRoot to memory leak objects. These objects will not be recycled, leading to memory leaks.


By finding the reference chain between the memory leak object and GCRoot, the source of the memory leak can be located and the memory leak problem can be solved. LeakCancry is implemented through this mechanism. Some common GCRoots include:

  • Object referenced in the virtual machine stack (Local Variable).

  • The object referenced by the static property (Static Variable) in the method area.

  • The object referenced by JNI.

  • Object referenced by Java thread (Thread).

  • Objects held by synchronized locks in Java.

Memory leak caused by anonymous inner class

Anonymous inner classes usually hold references to outer classes. If the life cycle of the outer class is longer than that of the anonymous inner class, (correction, the use of life cycle is not appropriate here. When the outer class is destroyed, the inner class will not be automatically destroyed. , because the inner class is not a member variable of the outer class, they are just objects created within the scope of the outer class, so the destruction timing of the inner class and the destruction timing of the outer class are different, so whether it will depend on whether the corresponding object exists The held reference) will cause the external class to be unable to be recycled, resulting in a memory leak.

Static variables hold references to Activity or Context

If a static variable holds a reference to an Activity or Context, then these Activity or Context cannot be recycled by the garbage collector, resulting in a memory leak.

Unclosed Cursor, Stream or Bitmap object

If the program does not properly close Cursor, Stream or Bitmap objects when using these objects, then these objects will continue to occupy memory, resulting in memory leaks.

Resources not released

If the program does not correctly release system resources when using them, such as not closing database connections, not releasing audio resources, etc., then these resources will continue to occupy memory, leading to memory leaks.

Common memory leaks

Memory leaks caused by static references

When an object is held by a static variable, even if the object is no longer used, it will not be recycled by the garbage collector, which will cause a memory leak.

public class MySingleton {
    private static MySingleton instance;
    private Context context;

    private MySingleton(Context context) {
        this.context = context;
    }

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

In the above code, MySingleton holds a reference to a Context object, and MySingleton is a static variable, which means that even if the object is no longer used, it will not be recycled by the garbage collector.

Note: If you need to use static variables, please be careful to set them to null when not needed so that the memory can be released in time.

Memory leak caused by anonymous inner class

The anonymous inner class will implicitly hold a reference to the outer class. If the anonymous inner class is held, the outer class will not be garbage collected.

public class MyActivity extends Activity {
    private Button button;

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

        button = new Button(this);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // do something
            }
        });
        setContentView(button);
    }
}

The anonymous inner class OnClickListener holds a reference to the external class MyActivity. If the button is not cleared before MyActivity is destroyed, MyActivity will not be garbage collected. (Button can be regarded as an object defined by yourself here. The general solution is to set the button object to empty)

Note: When the Activity is destroyed, all objects holding Activity references should be set to null.

Memory leak caused by Handler

Handler is a thread communication mechanism commonly used in Android applications. If Handler is used incorrectly, it will cause memory leaks.

public class MyActivity extends Activity {
    private static final int MSG_WHAT = 1;
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_WHAT:
                    // do something
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mHandler.sendEmptyMessageDelayed(MSG_WHAT, 1000 * 60 * 5);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 在Activity销毁时,应该将Handler的消息队列清空,以避免内存泄漏。
        mHandler.removeCallbacksAndMessages(null);
        }
}

The Handler holds a reference to the Activity. If there are unprocessed messages in the Handler's message queue before the Activity is destroyed, the Activity will not be garbage collected.


Note: When the Activity is destroyed, the Handler's message queue should be cleared to avoid memory leaks.

Memory leak caused by Bitmap object

When a Bitmap object is created, it will occupy a large amount of memory. If it is not released in time, it will cause a memory leak.

public class MyActivity extends Activity {
private Bitmap mBitmap;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // 加载一张大图
    mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.big_image);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    // 释放Bitmap对象
    mBitmap.recycle();
    mBitmap = null;
}
}

When the Activity is destroyed, the Bitmap object mBitmap should be released in time, otherwise it will cause a memory leak.

Note: When using a large number of Bitmap objects, unused objects should be recycled in time to avoid memory leaks. In addition, you can consider using image loading libraries to manage Bitmap objects, such as Glide, Picasso, etc.

Memory leaks caused by resources not being closed

When using some system resources, such as files, databases, etc., if they are not closed in time, memory leaks may occur. For example:

public void readFile(String filePath) throws IOException {
    FileInputStream fis = null;
    try {
        fis = new FileInputStream(filePath);
        // 读取文件...
    } finally {
        if (fis != null) {
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

In the above code, if the FileInputStream object is not closed in time after reading the file, it may cause a memory leak.


Note: When using some system resources, such as files, databases, etc., the relevant objects must be closed in time to avoid memory leaks.


To avoid memory leaks, you need to always pay attention when writing code, promptly clean up objects that are no longer used, and ensure that memory resources are released in a timely manner. At the same time, you can use some tools to detect memory leak problems, such as Android Profiler, LeakCanary, etc.

WebView memory leak

When using WebView, if it is not released in time, it may cause a memory leak.

public class MyActivity extends Activity {
    private WebView mWebView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mWebView = findViewById(R.id.webview);
        mWebView.loadUrl("https://www.example.com");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 释放WebView对象
        if (mWebView != null) {
            mWebView.stopLoading();
            mWebView.clearHistory();
            mWebView.clearCache(true);
            mWebView.loadUrl("about:blank");
            mWebView.onPause();
            mWebView.removeAllViews();
            mWebView.destroy();
            mWebView = null;
        }
    }
}

In the above code, when the Activity is destroyed, the WebView object should be released in time, otherwise it may cause a memory leak.

Note: When using WebView, you must release the WebView object in time. You can call the destroy method of WebView when the Activity is destroyed. At the same time, you must clear the history, cache, etc. of WebView to ensure that all resources are released.

Monitoring tools

  1. Memory monitoring tool: Android Studio provides a memory monitoring tool that can monitor the memory usage of applications in real time during the development process, helping developers discover memory leaks in a timely manner.

  2. DDMS: The DDMS tool in the Android SDK can monitor the processes and threads of Android devices or emulators, including memory usage, stack traces and other information, and can be used to diagnose memory leaks.

  3. MAT: MAT (Memory Analyzer Tool) is an Eclipse-based memory analysis tool that can analyze the heap memory usage of applications and identify and locate memory leaks.

  4. Tencent's Matrix is ​​also a very good open source project and is recommended for everyone to use.

2. Summary

A memory leak means that certain objects or resources in the program are not released properly, resulting in an increasing memory usage, which may eventually lead to application crashes or slow system operation.


Common memory leak problems include:

  1. Memory leaks caused by holding Activity or Fragment objects for a long time;

  2. Memory leaks caused by anonymous inner classes and non-static inner classes;

  3. Memory leak caused by WebView holding Activity object;

  4. Memory leaks caused by holding resource objects in singleton mode;

  5. Memory leaks caused by resources not being closed;

  6. Memory leaks caused by static variables holding Context objects;

  7. Memory leak caused by Handler holding external class reference;

  8. Memory leaks caused by Bitmap occupying a large amount of memory;

  9. Memory leaks caused by singletons holding large amounts of data.

To avoid memory leak problems, we can take the following measures:

  1. Release the Activity or Fragment object promptly;

  2. Avoid anonymous inner classes and non-static inner classes;

  3. When using WebView, call the destroy method promptly;

  4. Avoid holding resource objects for a long time in singleton mode;

  5. Close resource objects promptly;

  6. Avoid static variables holding Context objects;

  7. Avoid Handler holding external class references;

  8. When using Bitmap, release memory in time;

  9. Avoid singletons holding large amounts of data.

The above is a summary of Android performance optimization. Memory leak scenarios are different, and the optimization methods are not unique. Everyone is welcome to discuss together.

Guess you like

Origin blog.csdn.net/weitao_666/article/details/132336906