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免费资源。 这将防止你的堆首先变得碎片化。 网上有很多关于如何做到这一点的材料。 有些来自我的头顶:
StringBuilder
而不是普通的String
您只需使用其中的一小部分,即可确定堆的长度不会增长到很大的尺寸,从而衡量您的成功程度。
另一个想法是尝试使1.2MB的分配更小。通过使用较小的图像或在解码期间重新调整它们的大小。
链接地址: http://www.djcxy.com/p/93061.html