gpt4 book ai didi

android - 如何/何时收集处理程序垃圾?

转载 作者:IT老高 更新时间:2023-10-28 23:33:27 25 4
gpt4 key购买 nike

在我的一个类中,我有以下代码:

mHandler = createHandler();

private Handler createHandler() {
return new Handler() {
public void handleMessage (Message msg) {
update();
if (!paused) {
sendEmptyMessageDelayed(0, 300);
}
}
};
}

文档说:

http://developer.android.com/reference/android/os/Handler.html

Each Handler instance is associated with a single thread and that thread's message queue

所以如果我理解正确,只要应用程序线程正在运行,处理程序就不会被垃圾收集,对吗?

在我的具体示例中,由于 Handler 是一个匿名内部类,它具有对封闭对象的隐式引用以及它所指向的对象的整个层次结构。这在我看来就像是内存泄漏的秘诀。

顺便说一句,我可以让处理程序停止发送消息(这就是我有 if (!paused) 的原因)但这不会让它被 GCed,对吧?

那么有没有办法从消息队列中移除 Handler 并让它被 GCed 呢?

最佳答案

对 Handler 源代码的检查揭示了更多细节。

以下是 Romain Guy 添加的 Handler() 构造函数中的一些调试代码:

if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}

警告很明确:不要将 Handler 子类声明为内部类。

Handler的looper是从一个静态ThreadLocal实例中获取的:

mLooper = Looper.myLooper();

/**
* Return the Looper object associated with the current thread. Returns
* null if the calling thread is not associated with a Looper.
*/
public static final Looper myLooper() {
return (Looper)sThreadLocal.get();
}

泄漏解剖:

主应用线程保留 Looper 及其 MessageQueue,队列中的 Messages 保留指向其目标 Handler 的链接,并且 Handler——除非它是一个对你的 Activity 有 WeakReference 的静态嵌套类——将保留你的Activity 及其 View 。

您可以尝试通过清理您的消息来堵住这个漏洞:

handler.removeMessages(what);

但这说起来容易做起来难。

另见 On Memory Leaks in Java and in Android

关于android - 如何/何时收集处理程序垃圾?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5099218/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com