【问题标题】:Android Running apps memory usageAndroid 运行应用程序内存使用情况
【发布时间】:2012-11-12 00:43:55
【问题描述】:

我们在 Elipse 内存分析工具(在 DDMS 视图中)中看到的堆使用量(已分配)与此处显示的 Android 设备上同一应用程序的内存使用量大小有什么区别?:

设置->应用程序->运行

尽管我积极尝试通过在不需要对象时立即将对象设为 null 来保留内存,但后一个数字(运行应用程序屏幕上的内存使用量大小)只会不断增加,我的应用程序最终由于 OutOfMemoryError 而崩溃。然而,前者向我表明我的体型在合理范围内。我也经常调用 System.gc()。两者有区别吗?为什么会出现差异?关于如何解决这个问题的任何想法?

【问题讨论】:

  • 您在哪个 Android 版本上进行测试?您在使用位图吗?
  • 我实际上正在研究 ICS,但尽量保持向后兼容性。是的,我正在使用位图,这是我的恐惧 - 活动退出时不应该清除那些吗?显式 GC 之后呢?如果没有,我应该手动执行此操作吗?如何?无论如何,我使用的位图不是大文件 - 再现后它们的大小会增加吗?

标签: android memory-management out-of-memory


【解决方案1】:

如果内存从未被释放,听起来您的应用程序中某处存在内存泄漏。这意味着您在某处维护对正在重新创建的大对象(如活动或位图)的强引用,这就是为什么调用 System.gc() 没有任何区别。

我建议在 google IO 2011 上观看 memory management in android 上的以下内容。它让您知道如何使用 eclipse 内存分析器工具,该工具对于调试此类错误非常有用

【讨论】:

    【解决方案2】:

    据我所知,两者最大的区别在于垃圾回收的范围。

    正常的垃圾收集,包括System.gc(),会收集一些垃圾,然后停止。摆脱所有东西并不是彻底清除堆。也就是尽量减少垃圾回收对 CPU 的影响。

    不过,为 MAT 准备的堆转储实际上是一个完整的 GC。

    您的症状表明您分配内存的速度比 GC 回收它的速度要快。对此的主要解决方案是尝试分配更少的内存,或者减少分配它的频率。例如,在可能的情况下,重用对象、位图缓冲区等,而不是试图让 GC 清理旧的东西并随时分配新的东西。

    【讨论】:

    • 实际上,更具体地说,我有一些我最常使用的活动(类)成员对象,这些对象应该在方法返回后立即被 GC 处理,对吗?但这并不完全如此 - 内存只会不断增加,即使我另外将它们设为空。
    • @DivyanshGoenka:“我有一些我最常使用的活动(类)成员对象,这些应该在方法返回后立即被 GC,对吗?” -- 活动的非静态数据成员一旦活动被销毁,就有资格进行 GC。我不知道“只要他的方法返回”是什么意思。
    • 对不起,只是一个错字。我的意思是我通常会尽可能地限制我的成员的范围,以便他们更快地获得 GC。当这没有发生时,我什至开始在作用域的末尾将它们设为 null,认为这可能会有所帮助。然而,事实并非如此。我在问题中描述的两个数字之间存在巨大差异。是否有可能(尽管我不这么认为)显式 GC 实际上正在破坏它?有没有办法像你明确说的那样彻底扫除?
    • @DivyanshGoenka:“有没有可能(尽管我不这么认为)显式 GC 实际上破坏了它?” -- 我不知道是这种情况,但您可以简单地通过注释掉您的System.gc() 调用来测试它。 “有没有什么方法可以像你明确说的那样彻底扫除?” -- 我不知道,抱歉。
    猜你喜欢
    • 2014-11-08
    • 2011-09-20
    • 2015-05-25
    • 2011-03-09
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 2010-10-02
    • 1970-01-01
    相关资源
    最近更新 更多