Android Memory Optimization 11 memory leaks common Scenario 2 thread persistence

Source: Internet
Author: User

Thread Persistence

One feature of thread in Java is that they are directly referenced by GC root, which means that the Dalvik virtual machine has strong references to all activated threads, causing the GC to never reclaim these thread objects. Unless the thread is manually stopped and set to null or the user directly killed the process operation. So when using a thread, be sure to consider stopping the thread and releasing it in time when the activity exits

memory leak 1: AsyncTask
void startAsyncTask() {    new AsyncTask<Void, Void, Void>() {        @Override protected Void doInBackground(Void... params) { while(true); } }.execute();}super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);View aicButton = findViewById(R.id.at_button);aicButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startAsyncTask(); nextActivity(); }});

Memory leaks detected using leakcanary:

why not?
The above code creates an anonymous class asynctask in activity, with the same anonymous class and non-static inner class, which holds the outer class object, which is the activity, so if you declare and instantiate an anonymous Asynctask object in activity, A memory leak can occur, and if the thread is still executing in the background after the activity is destroyed, the thread will continue to hold the activity reference so that it will not be recycled by the GC until the thread executes.

How to solve?
Customize the static Asynctask class and keep the asynctask cycle and activity cycle consistent, i.e. cancel the asynctask at the end of the activity life cycle.

Memory leak 2:handler

The code is as follows:
Mainactivity.java

...void Createhandler () {New Handler () {@Override public void handlemessage (Message message) { super.handlemessage (message);}}. Postdelayed (new Runnable () { @Override public void run () {while (True);}}, 1000);}... . View Hbutton = Findviewbyid (R.id.h_button); Hbutton.setonclicklistener (new View.onclicklistener () { @ Override public void OnClick (View v) {createhandler (); nextactivity ();}}); ...

why not?

创建的Handler对象为匿名类,匿名类默认持有外部类activity, Handler通过发送Message与主线程交互,Message发出之后是存储在MessageQueue中的,有些Message也不是马上就被处理的。这时activity被handler持有
handler被message持有,message被messagequeue持有,message queue被loop持有,主线程的loop是全局存在的,这时就造成activity被临时性持久化,造成临时性内存泄漏

How to solve?
It can be seen from the above conclusion that the source of the leak is that the anonymous class holds the reference to the activity, so you can customize the handler and Runnable classes and declare them as static inner classes to disassociate and activity references. Or remove the message sent when the activity ends

Memory leak 3:thread

The code is as follows:
Mainactivity.java

void spawnThread() {    new Thread() {        @Override public void run() { while(true); } }.start();}View tButton = findViewById(R.id.t_button);tButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { spawnThread(); nextActivity(); }});

why not?
One feature of thread in Java is that they are directly referenced by GC root, which means that the Dalvik virtual machine has strong references to all activated threads, causing the GC to never reclaim these thread objects. Unless the thread is manually stopped and set to null or the user directly killed the process operation. See this believe you should also have the answer in mind: I have created a thread in each mainactivity, this thread will hold the mainactivity reference, even if the current thread exits the activity because it is directly referenced by GC root so it will not be recycled. Causing Mainactivity to be recycled by GC

How to solve?
When using a thread, be sure to consider stopping the thread and releasing it when the activity exits

memory leaks 4:timer Tasks

The code is as follows:
Mainactivity.java

void scheduleTimer() {    new Timer().schedule(new TimerTask() {        @Override        public void run() { while(true); } },1000);}View ttButton = findViewById(R.id.tt_button);ttButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { scheduleTimer(); nextActivity(); }});

why not?
The memory leak here is that the timer and TimerTask do not cancel, causing the timer and TimerTask to always refer to the external class activity.

How to solve?
Cancel at the right time.

Android Memory Optimization 11 memory leaks common Scenario 2 thread persistence

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.