当前位置:网站首页>How to effectively avoid memory leakage when customizing the handler?
How to effectively avoid memory leakage when customizing the handler?
2022-07-24 16:33:00 【Chen Xiaoxiang who wants to fly】
How to avoid customization handler Memory leak
Hello !
A term is used to explain
Inner class ( Click the jump ):
https://blog.csdn.net/chaseDreamer_/article/details/102859467
brief introduction
stay Android In the system ,Handler It is one of the core components of a message sending and processing mechanism , Other major components are Looper and Message,MessageQueue.
Message and Runnable Class is the carrier of message .MessageQueue It is the queue of message waiting .Looper Is responsible for getting messages from the queue .
effect
- Scheduling (scheule) Messages and executable runnable, It can be executed immediately or at a certain time in the future
- Let a certain behavior (action) Execute on other threads
About leakage
Handler It is a common way of asynchronous message processing provided by the system , Generally, it will not cause memory leakage , As for why it may lead to memory leakage , The memory leak here often refers to a leak Acitivity And so on
public class HandlerTestActivity extends Activity{
public Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
What's wrong with this writing ? The problem is that Handler The instance of adopts the writing method of inner class , It is HandlerTestActivity The inner class of this instance , stay Java in , There is a feature about inner classes : stay java in , Both non static inner classes and anonymous inner classes implicitly hold a reference to an outer class , As a result, external classes cannot be recycled by the system after use , This causes memory leaks .
Components with a shorter life cycle refer to components with a longer life cycle .Handler Is a typical example , Take the above code for example .HandlerTestActivity May be leaked , That is, the component is useless , For example, call finish() after , The garbage collector has been slow to recycle this Activity. The reason lies in the handler The inner class references it , And the handler Instances may be MessageQueue Quote . In fact, under normal circumstances, there will be no memory leakage , Unless handler Queue waiting too long , Want to solve handler Cause memory leaks , You need to understand the cause of the leak ,(handler hold activity, then message hold handler, then MessgQuene hold message), Understand this holding chain , that handler hold activity It can be solved by weak references or static inner classes , and removeCallbacksAndMessages Is to clear the following references , In fact, if your handler There are no time-consuming operations , Mission accomplished handler Will release Activity The reference of will not cause memory leakage ; Or your handler There is a 2 Second operation , stay Activity Exited 2s after , The release of the Activity References to , This is a short-term memory leak , It will also release , So you can ignore , But if yours handler If it's a dead cycle or something , It will lead to memory leakage .
From the above statement , We can think about the corresponding solutions :
1. Guarantee Activity By finish() The message queue of this thread does not have this Activity Of handler References to inner classes . This scene is extremely common , because handler It is often used to send delayed messages . One remedy is when this kind needs to be recycled , Manually empty the messages in the message queue :mHandler.removeCallbacksAndMessages(null);
2. Or let this handler Don't hold Activity And other external component instances , Let the Handler Become a static inner class .( Static inner classes do not hold instances of outer classes , Therefore, the external instance method cannot be called )
3. stay 2 Based on the method , In order to call external instance methods , Pass in an external weak reference )
4. take Handler Put it into a separate top-level class file .
Here we need to know about Java The knowledge quoted inside :
- Strong citation (Strong Reference) The default reference . If an object has a strong reference , The garbage collector will never recycle it . Empty in memory
When time is short ,Java The virtual machine would rather throw OutOfMemory Error of , Causes the program to terminate abnormally , It will not strongly reference objects to solve the problem of insufficient memory . - Soft citation (SoftReference) If there's enough memory , The garbage collector won't recycle it , If there's not enough memory , It will reclaim the memory of these objects .
- Weak reference (WeakReference) Once the garbage collector finds an object with only weak references , Whether the current memory space is enough or not , Will reclaim its memory .
- Virtual reference (PhantomReference) If an object only holds virtual references , Then it's the same as without any reference , Can be recycled at any time .
The third kind of , Need some extra code , More general .
public class HandlerTestActivity extends Activity {
private static class MyHandler extends Handler {
private final WeakReference<HandlerTestActivity> mActivity;
public MyHandler(HandlerTestActivity activity) {
mActivity = new WeakReference<HandlerTestActivity>(activity);
}
@Override
public void handleMessage(Message msg) {
ShanActivity activity = mActivity.get();
if (activity != null) {
//do Something
}
}
}
The fourth way , Extract and package separately .
/** * Implement callback weak reference Handler * Prevent memory leakage caused by internal holding * Incoming Callback Variables implemented anonymously cannot be used , Must be used with this Handle Object lifecycle one * Otherwise it will be released immediately */
public class WeakRefHandler extends Handler {
private WeakReference<Callback> mWeakReference;
public WeakRefHandler(Callback callback) {
mWeakReference = new WeakReference<Handler.Callback>(callback);
}
public WeakRefHandler(Callback callback, Looper looper) {
super(looper);
mWeakReference = new WeakReference<Handler.Callback>(callback);
}
@Override
public void handleMessage(Message msg) {
if (mWeakReference != null && mWeakReference.get() != null) {
Callback callback = mWeakReference.get();
callback.handleMessage(msg);
}
}
}
Because it is a weak reference , When this class needs to be recycled , Can be recycled directly .
WeakRefHandler The use of is as follows :
private Handler.Callback mCallback = new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
switch(msg.what){
}
return true;
}
};
private Handler mHandler = new WeakRefHandler(mCallback);
I was dreaming , Thank you for watching my blog , If there is any mistake , Please feel free to contact me ,QQ:897589417
边栏推荐
猜你喜欢
随机推荐
Long awaited full platform support - Open Source im project uniapp update of openim
Caikeng Alibaba cloud Kex_ exchange_ identification: read: Connection reset by peer
剑指 Offer 48. 最长不含重复字符的子字符串
剑指 Offer 25. 合并两个排序的链表
Microsoft Visio professional 2013 cannot be opened or uninstalled. Solution
Disassembly of Samsung Galaxy fold: the interior is extremely complex. Is the hinge the main cause of screen damage?
Mcd12q1 data shows multiple classifications in envi
REST风格
Complete guide on how to prevent cross site scripting (XSS) attacks
With regard to performance testing, dry goods hit "suggestions collection"
EventLoop event loop mechanism
EF data migration
TCP协议调试工具TcpEngine V1.3.0使用教程
Picture browser? QT can also be achieved!
Ligerui table control grid changes the color of rows (cells) according to the content
TCP protocol debugging tool tcpengine v1.3.0 tutorial
Template method mode
Host PSQL connecting virtual machine Oracle
C TCP client form application asynchronous receiving mode
Qt键盘事件(二)——长按按键反复触发event事件问题解决









