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