【问题标题】:Stack memory in AndroidAndroid中的堆栈内存
【发布时间】:2011-02-16 23:07:00
【问题描述】:

我正在编写一个应用程序,该应用程序具有前台服务、内容提供程序和绑定到服务并使用 AIDL 获取对象列表的 Activity 前端。该服务确实有效并更新了数据库。

如果我将活动打开 4-8 小时以上,然后转到手机 (Nexus One) 设置下的“运行服务”部分,则会显示正在使用的内存量异常大 (~42MB)。

我认为有泄漏。当我检查堆内存时,我得到堆大小:~18MB,~2MB 已分配,~16MB 可用。分析 Eclipse MAT 中的 hprof 似乎很好,这使我推断出堆栈上的内存泄漏。这甚至可能吗?如果是,我能做些什么来阻止或调查泄漏? android 的“运行服务”部分报告的内存使用情况是否正确(我认为是)?

另一个注意事项:当 UI 未启动(仅运行服务)时,我无法重现此问题

【问题讨论】:

    标签: android memory-leaks heap-memory stack-memory


    【解决方案1】:

    我正在编写一个具有 前台服务,内容提供者, 和一个绑定到的 Activity 前端 服务并返回一个列表 使用 AIDL 的对象。

    如果这只是一个应用程序,请摆脱 AIDL 并摆脱内容提供者。或者,至少不要自己使用它们——这些是供其他应用程序使用的。它们增加了您自己的虚拟机中不需要的开销。

    ...这使我推测堆栈上的内存正在泄漏。这甚至可能吗?

    不是真的。主应用程序线程堆栈非常小。其他线程的堆栈可能会变得更大,但如果你这样咀嚼 42MB,我会感到惊讶。

    如果是,我该怎么做才能停止或 调查泄漏?

    由于您已经完成了测试无 UI 并确定没问题的“尖峰解决方案”,我会慢慢重新引入 UI,看看您何时开始遇到问题。一个可能的候选问题区域是从后台线程更新活动,因此您可以将其关闭并看看会发生什么。

    由于您的问题不在堆本身,我的猜测是您的问题与位图或其他具有大量堆外 RAM 使用率的事物有关。你头像中的相机是这个方向的另一个提示。 :-) 确保你是recycle()-ing 你的位图等,看看是否有帮助。

    【讨论】:

    • 服务实际上是应用程序的主力,活动只是一个查看正在发生什么的窗口。我的印象是,真正将数据传回活动的唯一方法是绑定到服务并使用 AIDL 并打包对象。如果有更好的方法可以告诉我吗?我曾怀疑图像可能在早期有问题,并且已经退回到一个平铺背景 png 进行测试,大约为 40KB。所以我不认为是这样。我有一些使用图层可绘制对象(按钮、进度条)的 ui 元素,我不知道它们在堆外的效率如何。
    • 我最近尝试在应用程序中使用定时器的 leu 中的 ScheduledExecutorService,如果我不正确地关闭它,线程池是否可以无限期地留在内存中?今晚我将尝试恢复为基于 Timer 的解决方案,看看是否有任何改变。
    • 感谢您的回复顺便说一句,我担心没有人能帮助解决这个奇怪的问题。
    • 为了减少 AIDL/编组开销,请查看 Android 开发者网站上的 LocalService 示例。
    • 如果无论活动是否存在,您都在尝试工作,我真的不推荐ScheduledExecutorServiceTimer,因为这意味着您正在尝试运行永久服务。 androidguys.com/2009/09/09/… 对于该模式,请考虑 AlarmManagerIntentService,例如:github.com/commonsguy/cwac-wakeful 如果服务仅支持活动,请考虑在 View 上使用 postDelayed() Activity 和将调用调用到服务中,而不是反过来。
    猜你喜欢
    • 1970-01-01
    • 2011-08-01
    • 2011-08-15
    • 2011-10-09
    • 2016-04-05
    • 2017-02-08
    • 2012-06-03
    • 2021-04-08
    • 2013-05-26
    相关资源
    最近更新 更多