java.lang.OutOfMemoryError: android.support.v4.app.BackStackState[] of length 1279544898 would overflow

java.lang.OutOfMemoryError: android.support.v4.app.BackStackState[] of length 1279544898 would overflow

这些崩溃在返回我的主 activity 时间歇性地发生,它由两个片段组成(一个是 Google 地图支持片段)。如果不是我们的崩溃跟踪系统,我不知道用户会遇到这种情况,因为它无法在我的任何物理或模拟设备上重现。它跨越了我的最小值 15 和我的目标值 22 之间的各种 APIs。

在崩溃系统中,崩溃以两种形式之一发生:

java.lang.OutOfMemoryError: android.support.v4.app.BackStackState[] of length 1279544898 would overflow

java.lang.OutOfMemoryError: Failed to allocate a 5118179604 byte allocation with 16777216 free bytes and 472MB until OOM near/at g.newArray:174

崩溃发生在包含我的地图的片段的 onViewCreated 方法中:

mMapView.onCreate(savedInstanceState);

我的第一个想法是内存泄漏,但是......看起来它在创建后台堆栈时正在循环 - 好像后台堆栈的索引已经溢出了很长时间。 Leak Canary 没有发现任何内存泄漏(除了我们的 MainApplication,我知道它保留了对上下文的静态引用)。如果这是典型的内存泄漏,那么这种崩溃总是发生在同一行而不是其他地方似乎很奇怪。这个应用程序还有其他内存密集型区域(这是企业级的,所以我不能透露太多),但是 none 这些其他活动引发了 OOM 错误。

我还应该指出,这是一个成熟的应用程序,拥有许多用户和版本。 OOM 问题仅出现在我们当前版本的测试版中(同样,仅基于我们的崩溃跟踪系统的记录,因为我们无法在任何地方重现)。我已经对我们的生产版本和我们的测试版进行了彻底的代码比较,并且大多数更改都是相对 standard/trivial。 (我还没有开始添加新的位图或任何东西。)

规格:

还有其他人看到了吗?我可以看到崩溃正在发生,但是当我无法重现它时很难追踪到它...

回答我自己的问题...

我能够通过在开发人员选项中启用“不要保留活动”来重现错误。

经过三天的测试,我最终发现我们的构建服务器正在编译支持 24 而不是我在 Gradle 中指定的支持 22。显然,支持 24 和 android 映射之间存在一些不兼容性。通过更改:

compile 'com.android.support:support-v4:22.2.0'

compile('com.android.support:support-v4:22.2.0') {
    force = true
}

因此迫使 Gradle 取 22 个而不是后来可用的 24 个,循环后栈消失了。现在我不再看到我们的测试版用户出现 OOM。

我推测这与 API 的权限模型更改有关,但谁知道呢。

无论如何...希望这对某人有所帮助。