安卓运行的应用程序内存使用情况

4
在Eclipse Memory Analysis Tool(DDMS视图中)看到的堆使用情况(已分配)与在Android设备上显示的相同应用程序的内存使用大小之间有什么区别?即使我通过将对象设置为null来尽可能地保留内存,后者(在“运行中的应用程序”屏幕上显示的内存使用大小)仍然不断增加,最终导致我的应用程序崩溃并出现OutOfMemoryError。但前者向我展示我已经远远在合理范围内。我也频繁调用System.gc()。两者之间是否有差异?为什么会出现这种差异?您对如何解决这个问题有什么想法吗?

你在哪个 Android 版本上进行测试?你正在使用 Bitmaps 吗? - Amokrane Chentir
我目前正在开发ICS,但尽量保持向后兼容性。是的,我正在使用位图,这让我有些担心 - 当Activity退出时,它们不应该被清除吗?显式GC之后呢?如果没有,那我应该手动清除吗?怎么做?无论如何,我使用的位图文件并不大 - 渲染后它们会增加大小吗? - Divyansh Goenka
2个回答

1

我所知道的两者之间最大的区别是垃圾回收的范围。

普通的垃圾回收,包括System.gc(),会收集一些垃圾,然后停止。它不是对堆进行完全扫描以清除所有内容。这是为了尽量减少垃圾回收对CPU的影响。

为MAT准备的堆转储实际上是完整的GC。

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


实际上,更具体地说,我有一些活动(类)成员对象,我主要使用它们,这些对象应该在方法返回时被垃圾回收,对吧?但事实并非完全如此 - 即使我将它们设置为null,那些内存仍然不断增加。 - Divyansh Goenka
@DivyanshGoenka:“我有一些活动(类)成员对象,我主要使用它们,这些应该在方法返回后尽快被GC清除,对吗?”-- 活动的非静态数据成员在活动销毁后就可以进行垃圾回收。我不知道“尽快在方法返回时”是什么意思。 - CommonsWare
抱歉,只是一个打字错误。我的意思是尽可能限制成员的范围,以便更快地进行垃圾回收。当这种情况没有发生时,我甚至开始在作用域结束时将它们设置为null,以为这样会有所帮助。然而,事实并非如此。我在问题中描述的两个数字之间存在巨大差异。虽然我不认为这是可能的,但显式GC是否实际上破坏了它?是否有任何方法可以像您明确说明的那样进行完整的扫描? - Divyansh Goenka
@DivyanshGoenka:“虽然我不认为可能,但显式GC是否实际上破坏了它?”--我不知道这是否是事实,但您可以通过注释掉System.gc()调用来测试它。 “有没有办法像你说的那样进行完整的扫描?”--很抱歉,我不知道有没有这样的方法。 - CommonsWare

0

如果内存从未释放,那么你的应用程序中可能存在某处内存泄漏。这意味着你在某个地方保持了对一个大对象的强引用,该对象正在被重新创建(例如Activity或Bitmap),这就是为什么调用System.gc()没有任何效果的原因。

我建议观看来自Google IO 2011的Android内存管理视频。它可以让你了解如何使用Eclipse内存分析器工具,该工具对于调试此类错误非常有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接