【问题标题】:Android app memory heap keeps growingAndroid 应用内存堆不断增长
【发布时间】:2013-01-09 20:01:56
【问题描述】:

我的应用程序出现随机(内存不足)崩溃,因此我开始分析我的堆。我注意到,如果我从活动 A 转到活动 B,堆会从 27 MB 增加到 35 MB(由于延迟加载许多图像)。但是,当我完成()活动 B 以返回活动 A 时,即使使用 GC 操作,堆大小也保持不变!

令人讨厌的是,再次执行活动 B 会将堆增加到 42 MB。我可以多次这样做,而且堆只会不断增加。

这是我正在使用的延迟图像加载库:

懒惰列表https://github.com/thest1/LazyList

这些是堆的截图

之前:http://i.stack.imgur.com/7eTzm.png

之后:http://i.stack.imgur.com/txeC6.png

转换后的堆转储文件可根据要求提供

更新

从我的调试来看,似乎是来自 LazyList 库的问题,但我仍然不能 100% 确定。以下是对图书馆评论的人的参考:

https://github.com/thest1/LazyList/issues/20

【问题讨论】:

  • 听起来您的活动正在泄漏一些数据。您是否有任何 IPC 成员变量,或者任何其他可以在没有活动的情况下继续进行的内容?
  • 没有 IPC 为了在没有活动的情况下继续,我正在使用的库使用多个线程(汽车在没有活动的情况下运行)。
  • 你解决了这个问题然后请反馈..

标签: android memory-management memory-leaks garbage-collection heap-memory


【解决方案1】:

我的猜测是您正在泄漏活动(这可能会泄漏它拥有的所有变量)。确保任何需要您传递上下文的操作系统调用都已取消注册,您没有任何对象持有对活动的引用(尤其是通过持有上下文),并且您可以在 onDestroy 中清除所有内容或 onStop(在所有主要对象中也这样做)。

如果这还不够,请查看您的 hprof 并查看您终止活动后周围有哪些大对象以及谁持有引用。修复并重复。

【讨论】:

  • 如何取消注册需要传递上下文的操作系统调用?你能给我举个例子吗?
  • 你在哪里使用上下文?如果它在侦听器中,您可能需要摆脱它。但总的来说,我认为您不需要像以往一样保留从 Activity A 到 Activity B 的引用。
  • 我同意这一点。但是将 Context 对象传递给将它们存储为成员变量的侦听器或数据对象并不少见,如果您不将它们清空,您将泄漏。后来决定将这些变量设为单例或全局变量,甚至并不少见,而不是考虑周围存在的上下文变量(哎呀,它甚至可能已传递给执行此操作的其他对象的构造函数,但您只是将原始对象放置在周围)。这样做的常见原因是访问 SharedPreferences 或 XXXManager 类等内容。
  • @dmon 我如何摆脱监听器内部的上下文?
  • @GabeSechan 但为什么活动 A 中的任何侦听器都会引用活动 B? AlAsiri:你不能。您必须停止引用侦听器。
【解决方案2】:

在我看来,您每次都在开始一项新活动,而不是切换到已加载的活动。尝试在切换活动时设置意图的标志以包含 Intent.FLAG_ACTIVITY_REORDER_TO_FRONT。

See this

【讨论】:

  • 我认为这不是问题,因为已经打开的活动应该被 GC 清理,原因是由于内存泄漏,活动引用被某个引用持有并且活动实例无法清理..
【解决方案3】:

在我看来,这可能是您正在使用的图像。 BitmapFactory from Android 创建不可变位图,因此您对这些位图所做的任何更改都将与原始图像分开。

更糟糕的是,即使您将其告知recycle,它是否会被垃圾收集也将取决于您的参考。

【讨论】:

猜你喜欢
  • 2016-02-24
  • 2012-01-11
  • 2015-11-11
  • 1970-01-01
  • 2013-10-20
  • 1970-01-01
  • 2017-11-09
  • 1970-01-01
  • 2015-06-15
相关资源
最近更新 更多