Android和运行OOM并剩下可用堆空间

我有一个应用程序运行OOM,有大量免费堆空间,可用于在Galaxy S3上增长。 该应用在其他设备上运行良好。

了解到在传统的Java中,这可能是由永久代中的OOM造成的,我试图研究Dalvik如何处理这个问题,但找不到任何确定性的东西。 Androids SDK似乎缺少了MemoryUsage和ManagementFactory,所以我无法像使用Java那样获取它们。

我试图找出Android是否具有永久生成空间,我可以检查它的内容,我如何获得大小和空闲,Dalvik是否处理与JVM等不同的空间。

如果这个空间不存在或者不太可能,也向其他想法敞开。

有关应用程序的一些信息。 运行OOM的S3正在运行4.1.2。 该应用程序使用大约12-25 MB的堆,可用的最大堆大小约为45MB。 它有很多本地资源图像,并且延迟加载更多。 我是.recylce()位图。 该应用程序每次都在大致相同的位置崩溃。 我仔细研究了现场的代码崩溃,我没有看到任何不寻常的东西。 其他设备运行此代码就好了。


在我看来,你遇到了堆碎片问题。

您在具有大量可用空间的堆中的1.2MB分配上失败。 系统可能无法找到1.2MB的连续空块,因为您的堆完全分段,并且无法进一步扩大您的堆。

理论上,你不应该担心碎片问题,自动GC会为你处理它。

实际上,我不止一次看到,给系统GC一个援助之手有时会取得巨大的成果。

以下是解决碎片问题的一些想法:

  • 在战略位置手动运行System.gc() 。 常见的位置是在销毁大型物体(如onDestroy活动)期间。 其他地方在像Bitmaps这样的大型分配之前。 在解码任何大型位图之前,请添加手动GC。 如果您想稍后减少GC的数量,请通过查询各种堆大小函数来为有问题的内存条件添加手动测试。

  • 更快地协助系统GC免费资源。 这将防止你的堆首先变得碎片化。 网上有很多关于如何做到这一点的材料。 有些来自我的头顶:

  • 如果你有频繁的小分配,尝试采用内存重用方案,比如创建一个对象池,并重用池中的对象,而不是分配新对象。 这种优化经常出现在android适配器中(比如视图在列表视图中的重用)
  • 当你不需要它们时,手动设置变量为null,以便明确地将它们与参考图断开连接并将它们标记为便于GC(同样可以明确地清除数据收集)
  • 当你有足够的操作时,避免不可变的类,比如字符串的连接,使用StringBuilder而不是普通的String
  • 完全避免终结器
  • 避免循环引用,或者至少将其中的一个改为弱引用
  • 通常在需要的地方使用弱引用
  • 您只需使用其中的一小部分,即可确定堆的长度不会增长到很大的尺寸,从而衡量您的成功程度。

    另一个想法是尝试使1.2MB的分配更小。通过使用较小的图像或在解码期间重新调整它们的大小。

    链接地址: http://www.djcxy.com/p/93061.html

    上一篇: Android and running OOM with free heap space left

    下一篇: Memory metrics in android apps