首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解Android应用程序中的内存泄漏

理解Android应用程序中的内存泄漏
EN

Stack Overflow用户
提问于 2015-05-14 19:36:55
回答 3查看 730关注 0票数 5

我对Java编程相当陌生,有着丰富的C++经验,我正在阅读有关引用如何导致Android应用程序中内存泄漏的文章。这一解释把我搞糊涂了。“第二课”上写着:

关键是,活动不知道SomeObject的生命周期将在活动实例结束时结束。如果那个物体留在内存中,它也会将该活动保存在内存中.

在我看来(可能错了,请纠正我),当活动结束时,SomeObject就被销毁了(假设没有其他引用)。活动引用SomeObject,而不是相反。我不明白为什么这里会泄露任何东西,更不用说整个活动了。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-05-14 19:46:17

这与他们为EventListener创建匿名类的事实有关。

代码语言:javascript
复制
public void onResume() {
    super.onResume();

    SomeObject object = new SomeObject();

    object.setSuccessListener(new EventListener<Boolean>() {
        public void onEvent(Boolean response) {
            Log.d(TAG_NAME, "Valid response? "+response);
        }
    });

    SomeObjectManager.getSingleton().addObject(object);
}
  • 它明确指出这是在活动的onResume()中完成的。
  • 匿名类(以及非静态内部类)具有对其周围类的隐式引用。因此,在这种情况下,EventListener有一个对活动本身的引用。
  • 因此,SomeObject对活动有一个引用,因为它引用了实现EventListener的匿名类。

以下是你在问题中引用的引文之前的文字:

例如,在上面的示例中:我们已经将对活动实例的引用附加到某个对象(可能是持久的)以及某个管理器中。重点是..。

因此,当活动被销毁时,SomeObjectManager类不会消失,它包含对SomeObject的引用,而SomeObject保存对EventListener的引用,而EventListener引用该活动。

所以当你说:

在我看来(可能错了,请纠正我),当活动结束时,SomeObject就被销毁了(假设没有其他引用)。活动引用SomeObject,而不是相反。

该逻辑中的缺陷是,SomeObject通过EventListener引用该活动。

这有用吗?

票数 2
EN

Stack Overflow用户

发布于 2015-05-14 19:52:56

以下是答案:这次逃亡是怎么回事?

如果可以这样做,那么在调试器中运行它并设置断点:

代码语言:javascript
复制
Log.d(TAG_NAME, "Valid response? "+response);

现在检查一下哪些成员执行“this”实例。特别是您对this$0感兴趣。

所以这个呼吁是很重要的:

代码语言:javascript
复制
objectFromBefore.setSuccessListener(null);

看看之前发生了什么:

代码语言:javascript
复制
object.setSuccessListener(new EventListener<Boolean>() {
    public void onEvent(Boolean response) {
        Log.d(TAG_NAME, "Valid response? "+response);
    }
});

SomeObjectManager.getSingleton().addObject(object);

现在这条链是:

SomeObjectManager ->单例-> listofObjects ->对象

就目的而言:

对象->后继列表->匿名EventListener->此$

这里的$是您的外部实例,它是活动。

票数 2
EN

Stack Overflow用户

发布于 2015-05-14 21:46:52

不幸的是,很容易泄露一个活动。我认识的一些Android开发者很高兴(有时是故意的)对这个事实置若罔闻。感谢你的关心,让你知道你想学到更多的东西来避免这种情况。

您可以泄漏活动的一些常见方法

1)将活动设置/添加/注册为侦听器或观察者,并忘记设置(Null)/删除/注销活动。

2)将对活动的引用传递给使用静态引用而不是清除静态引用的任何保持该活动的引用。(单身人士就是一个例子)

3)使用非静态内部类。(匿名内部类处理程序就是一个例子)

您可以做一些事情来避免这些类型的泄漏,

1)记得设置(Null)/删除/注销您的活动

2)作为软件设计的一部分,在处理活动的组件中加入活动生命周期的概念。

3)使内部类保持静态,在需要引用外部类的地方,使用WeakReferences

4)尽可能使用应用程序上下文而不是活动上下文。

一些常见的情况,在此情况下,您的活动将被破坏并重新创建

1)如果你允许你的应用程序改变方向,当你从肖像转向风景时,这个活动将会被破坏和重新创造,反之亦然。

2)使用设备的后退按钮退出应用程序将导致当前的活动被破坏(尽管应用程序本身将保持运行状态)。

3)虽然更罕见,但Android可以随意杀死您的活动,以便释放资源,并使设备响应用户的需求。

您应该熟悉Android的设备监视器、hprof-conv工具和Eclipse内存分析器工具。我找到了最简单的方法来测试我的应用程序,看看它是否泄露了一个活动,当我进入应用程序时,将它存储在设备监视器中,使用设备返回按钮退出,然后点击应用程序托盘中的图标返回应用程序。重复几次,然后创建一个内存转储文件。在此转储文件上运行hprof-conv工具,将其转换为MAT可以理解的格式,然后在MAT中打开它。

有很多关于获取内存配置文件和使用MAT的教程。只是做一个网络搜索。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30245859

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档