对局部变量的匿名类隐藏引用



我在我的Android应用程序中遇到了报告的内存泄漏,经过一些调查,我几乎找到了泄漏的位置,这是简化的代码:

public class LeakTracker {
public static List<Callback> callbacks = new ArrayList<>();
public static List<WeakReference<LeakingActivity>> weakList = new ArrayList<>();
// causes leak of activity
public void startLeak(final LeakingActivity activity) {
callbacks.add(new Callback() {
// remove this line then no leak
Wrapper wrapper = new Wrapper(activity);
@Override
public void onCall() {
}
});
}
// no leak here
public void startLeak2(final LeakingActivity activity) {
weakList.add(new WeakReference<>(activity));
}
public interface Callback {
void onCall();
}
static class Wrapper {
private WeakReference<LeakingActivity> weakReference;
public Wrapper(final LeakingActivity activity) {
weakReference = new WeakReference<LeakingActivity>(activity);
}
}
}

发生泄漏是因为我调用函数"startLeak"。活动变量将被泄露。但是,如果我调用"startLeak2",泄漏就不会发生。我想知道为什么在第一种情况下会泄漏。包装器也使用弱引用。

LeakActivity 类占用大约 30M 的内存。在Android设备上调用startLeak大约5次会导致OOM。调用 startLeak2 不会。如果使用 startLeak 而不是 startLeak2,则 LeakCanary 工具报告泄漏。

在第一种方法上,您已将活动声明为 final。这会将活动的引用添加到Callback实例,因此泄漏的不是Wrapper,而是Callback本身。

另外,请记住,Callback是一个匿名的内部类,它还将保存对外部类的引用LeakTracker

相关内容

  • 没有找到相关文章

最新更新