我有一个OpenGL Android应用程序,它使用大量内存来设置复杂的场景,这显然会导致严重的堆碎片。即使没有内存泄漏,也不可能破坏和创建应用程序而不会由于碎片而耗尽内存。 (碎片肯定是问题,而不是泄漏)
这会导致一个主要问题,因为Android有在同一个VM /堆上销毁和创建活动的习惯,这显然会导致活动崩溃。作为解决这个问题的策略,我使用了以下技术:
@Override
protected void onStop() {
super.onStop();
if(isFinishing()) {
System.runFinalizersOnExit(true);
System.exit(0);
}
}
这可确保在活动完成时导致完整的VM关闭,因此下次启动活动时会获得一个新的未碎片堆。
注意:我意识到这不是“Android方式”,但考虑到垃圾收集器是非压缩的,不可能不断重复使用堆。
这项技术实际上确实有效,但是当活动在非完成模式下销毁然后重新创建时它不起作用。
有没有人对如何处理堆的降级有任何好的建议?
进一步说明:减少内存消耗也不是一种选择。该活动实际上并没有使用那么多内存,但堆(和本机堆)似乎很容易碎片化,可能是由于一些大的内存块
答案 0 :(得分:4)
碎片几乎总是病态分配模式的结果。经常创建和销毁大型对象。与较小的对象一起可以持久化(或者至少具有不同的生命周期) - 创建堆中的孔。
在这种情况下,唯一可行的碎片预防措施是:防止特定的分配模式。这通常可以通过汇集大对象来完成。如果成功,应用程序将以更好的执行速度表示感谢。
@edit:更具体的问题是:如果重启应用程序后的堆还没有为空,那么堆上还有什么?你确认它不是内存泄漏的问题,但这就是它看起来的样子。既然你正在使用OpenGL - 它可能是,一些原生包装器幸存下来,因为OpenGL资源没有被正确处理?