Android 堆碎片化策略?

Posted

技术标签:

【中文标题】Android 堆碎片化策略?【英文标题】:Android Heap Fragmentation Strategy? 【发布时间】:2012-03-18 05:41:46 【问题描述】:

我有一个 OpenGL android 应用程序,它使用大量内存来设置复杂的场景,这显然会导致严重的堆碎片。即使没有内存泄漏,也无法在不因碎片而耗尽内存的情况下销毁和创建应用程序。 (碎片肯定是问题,而不是泄漏)

这会导致一个重大问题,因为 Android 习惯于在同一个 VM/堆上销毁和创建 Activity,这显然会导致 Activity 崩溃。作为应对这种情况的策略,我使用了以下技术:

@Override
protected void onStop() 
    super.onStop();
    if(isFinishing()) 
        System.runFinalizersOnExit(true);
        System.exit(0);
    

这可确保当活动完成时,它会导致虚拟机完全关闭,因此下次启动活动时,它会获得一个新的未碎片化堆。

注意:我意识到这不是“Android 方式”,但鉴于垃圾收集器是非压缩的,因此不可能持续重用堆。

这种技术实际上确实可以正常工作,但是当 Activity 在非完成模式下被销毁然后重新创建时,它就不起作用了。

有人对如何处理堆的退化有任何好的建议吗?

进一步说明:减少内存消耗也不是一个真正的选择。该活动实际上并没有使用那么多内存,但堆(和本机堆)似乎很容易碎片化,可能是由于一些较大的内存块

【问题讨论】:

我遇到了同样的问题,并采用了类似的解决方案。真的很糟糕。 【参考方案1】:

碎片几乎总是病态分配模式的结果。大对象经常被创建和销毁。结合较小的对象可能会持续存在(或至少具有不同的生命周期) - 在堆中创建洞。

在这种情况下,唯一有效的碎片预防措施是:防止特定的分配模式。这通常可以通过汇集大对象来完成。如果成功,该应用程序将谢天谢地以更快的执行速度承认这一点。

@edit:更具体的问题是:如果应用程序重新启动后堆还不是空的,那么堆上还有什么?您确认这不是内存泄漏的问题,但这就是看起来的情况。由于您使用的是 OpenGL - 可能是因为未正确处理 OpenGL 资源,因此一些本机包装器幸免于难吗?

【讨论】:

以上是关于Android 堆碎片化策略?的主要内容,如果未能解决你的问题,请参考以下文章

Android碎片化达到顶峰:近10亿设备已“过时”

腾讯优测优分享-Android平台的碎片化问题解决

高级UI之Android屏幕适配全方位解析

腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿

信息爆炸下, 让碎片化阅读从未如此高效简单,一键整理碎片化知识

Android屏幕适配