Android effectively solves the problem of memory leakage

Android effectively solves the problem of memory leakage

Android memory leaks. I have a headache when I want to make Android applications. Here are some good materials I found on the Internet, examples and solutions to this problem

Recently, I have been studying the knowledge of handler, which involves a problem, how to avoid the memory overflow caused by handler. I have found a lot of information on the Internet. Many of them are copied from each other, which has no practical effect.

The memory leak detection tool in this article is leakcanary GitHub address: https://github.com/square/leakcanary

What is a memory leak?

Memory leak is the failure to release memory when the program no longer uses the memory, resulting in useless memory consumption. Memory leakage does not mean the disappearance of physical memory. The memory leakage here is the memory allocated by the program, but the program loses control of the memory due to program logic errors, resulting in a waste of memory.

What causes memory leaks?

Memory leakage caused by the failure to close the resource object, such as the failure to close the cursor after querying the database

When constructing an adapter, convertview reuse is not used

Call recycle() to free memory when the bitmap object is not in use

The object is referenced by an object with a long life cycle. For example, the activity cannot be released because it is referenced by a static collection

What are the hazards of memory leaks?

Memory leakage does no direct harm to the app. Even if there is a memory leakage in the app, it will not necessarily cause the app to crash, but it will increase the occupation of APP memory. If the memory is not released, it will slowly cause app memory overflow. Therefore, the purpose of solving memory leakage is to prevent app memory overflow.

1. Activity memory leak caused by new thread

example:

After running the above code, click the finish button, and a memory leak occurs after a while.

@H_ 502_ 50@

Why does activity6 have a memory leak?

Enter the activity6 interface and click finish. Activity6 is destroyed, but the threads in activity6 are still running. The anonymous internal class runnable object references the instance of activity6, so the memory occupied by activity6 cannot be recycled by GC in time.

How to improve?

Change runnable to a static non anonymous inner class.

2. Activity memory leak caused by adding listener to activity

This is a common mistake in development, nastymanager GetInstance () is a singleton. When we bind activity as listener and nastymanager through addListener (this), bad things happen.

How to improve?

To fix such a bug, it's actually quite simple. When your activity is destroyed, just unbind it from nastymanager.

3. Memory overflow caused by anonymous inner class of handler?

Look at a piece of code first

After this code runs, click Finish immediately. Through detection, it is found that handleractivity has a memory leak. After activity finish, the delayed message will continue to exist in the message queue of the main thread for 8 seconds, and then the message will be processed. The message refers to the handler object of the activity, and then the handler refers to the activity. These reference objects will remain until the message is processed, so that the activity object cannot be recycled, resulting in the above activity disclosure. Handler is a very common and useful class, asynchronous, thread safety and so on. What happens if you have code like this? handler. Postlaid, suppose the delay time is a few hours... What does that mean? It means that as long as the handler's message has not been processed, it will always live, and the activity containing it will live. Let's find a way to repair it. The repair scheme is WeakReference, that is, the so-called weak reference. The garbage collector will ignore weak references when collecting, so the activities containing it will be cleaned up normally.

How to avoid

Using static inner classes

Use weak references

The modified code is like this.

This handler already uses static inner classes and weak references. However, this does not completely solve the memory leakage problem of handleractivity. The culprit is the problem of thread creation, just like the first example in this article. The improved way is to write the runnable class as a static inner class.

The final complete code is as follows:

Wait, it's not over yet?

The above code has effectively solved the problem of memory leakage caused by handler and runnable referencing activity instances, but this is not enough. The core reason for memory leakage is that when an object should be recycled by the system, it is referenced by other objects, so that the memory cannot be recycled. So when we write code, we should always stick to this string. Returning to the above question, when the current activity calls finish to destroy, should all threads in the activity be cancelled in the ondestory () method. Of course, whether to cancel the asynchronous task depends on the specific requirements of the project. For example, when the activity is destroyed, start a thread and asynchronously write the log to the local disk. For this requirement, you need to start the thread in the ondestory () method. Therefore, making a choice according to the current environment is the positive solution.

So we can also modify the code to remove all callbacks and messages in ondestroy().

4. Asynctask caused a memory leak

Why?

The above code creates an anonymous class asynctask in the activity. The anonymous class is the same as the non static internal class and will hold the external class object, here is the activity. Therefore, if you declare and instantiate an anonymous asynctask object in the activity, memory leakage may occur. If this thread is still executing in the background after the activity is destroyed, Then the thread will continue to hold the reference of the activity and will not be recycled by the GC until the thread execution is completed.

How?

Custom static asynctask class A

The cycle of synctask is consistent with the activity cycle. That is, the asynctask should be cancelled at the end of the activity life cycle.

5. Memory leak caused by timer tasks

Why?

The memory leak here is that the timer and TimerTask do not cancel, resulting in the timer and TimerTask always referring to the external class activity.

How?

Cancel at the right time.

Static inner class for TimerTask

Note: I saw some information on the Internet that TimerTask memory leak can be solved by canceling at an appropriate time. After testing, it is proved that there is still a memory leakage problem when canceling at the right time. So be sure to use static inner classes.

Thank you for reading, hope to help you, thank you for your support to this site!

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>