Android应用后台切换返回后因导航引发OutOfMemoryError求助
应用后台切换后返回出现OutOfMemoryError,疑似与导航组件相关
将应用置于后台,切换多个应用后返回时出现卡顿,并抛出OutOfMemoryError,初步怀疑和导航组件有关。报错堆栈如下:
java.lang.OutOfMemoryError: Failed to allocate a 24 byte allocation with 77088 free bytes and 75KB until OOM, target footprint 268435456, growth limit 268435456; giving up on allocation because <1% of heap free after GC. at java.util.HashMap.newNode(HashMap.java:1746) at java.util.HashMap.putVal(HashMap.java:630) at java.util.HashMap.put(HashMap.java:611) at java.util.HashSet.add(HashSet.java:219) at java.util.Collections.addAll(Collections.java:5458) at com.google.android.play.core.splitinstall.zzs.zzh(com.google.android.play:core@@1.10.3:13) at com.google.android.play.core.splitinstall.zzs.zzc(com.google.android.play:core@@1.10.3:2) at com.google.android.play.core.splitinstall.zzaa.getInstalledModules(com.google.android.play:core@@1.10.3:1) at com.google.android.play.core.splitinstall.zzl.getInstalledModules(com.google.android.play:core@@1.10.3:1) at androidx.navigation.dynamicfeatures.DynamicInstallManager.needsInstall(DynamicInstallManager.kt:100) at androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.onRestoreState(DynamicIncludeGraphNavigator.kt:158) at androidx.navigation.NavController.onGraphCreated(NavController.kt:1114) at androidx.navigation.NavController.setGraph(NavController.kt:1086) at androidx.navigation.NavController.setGraph(NavController.kt:1039) at androidx.navigation.fragment.NavHostFragment.onCreate(NavHostFragment.kt:155) at androidx.fragment.app.Fragment.performCreate(Fragment.java:3090) at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:475) at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:257) at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:142) at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:136) at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:248) at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:227) at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1073) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1001) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:965) at android.view.LayoutInflater.rInflate(LayoutInflater.java:1127) at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1088) at android.view.LayoutInflater.inflate(LayoutInflater.java:686) at android.view.LayoutInflater.inflate(LayoutInflater.java:538) at vn.com.vndirect.stocks.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:44) at vn.com.vndirect.stocks.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:38) at vn.com.vndirect.stocks.MainActivity.onCreate(MainActivity.kt:56) at android.app.Activity.performCreate(Activity.java:8051) at android.app.Activity.performCreate(Activity.java:8031) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3612) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3796) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2214) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7842) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
核心定位
从堆栈轨迹看,OOM发生在导航组件恢复动态模块状态的过程中:DynamicIncludeGraphNavigator.onRestoreState调用DynamicInstallManager.needsInstall,进而触发Play Core的getInstalledModules方法,在HashMap分配节点时内存不足。结合后台切换场景,问题大概率是应用被系统回收重建时,导航组件的动态模块状态管理出现内存泄漏或重复占用。
排查建议
- 检查动态导航配置:确认
DynamicIncludeGraph是否存在重复注册、未正确解绑的情况,比如是否在多个Fragment/Activity中重复加载同一动态导航图,导致模块信息被多次存储。 - 内存泄漏检测:
- 用Android Studio Profiler捕获应用后台切换前后的内存快照,对比
DynamicInstallManager、NavController、NavHostFragment相关对象的引用情况,排查是否有静态引用、长生命周期对象持有这些导航组件实例。 - 使用LeakCanary工具自动检测内存泄漏,重点关注导航相关对象的泄漏路径。
- 用Android Studio Profiler捕获应用后台切换前后的内存快照,对比
- 升级依赖版本:当前使用的Play Core版本为1.10.3,该版本存在已知的动态模块管理内存问题,建议升级到1.12.0及以上版本;同时同步升级Navigation组件到对应兼容版本。
- 优化导航初始化逻辑:检查
MainActivity或NavHostFragment的onCreate方法,是否重复调用setGraph导致多次触发动态模块检查,可通过判断导航图是否已初始化避免重复操作。 - Heap配置验证:虽然报错显示Heap增长限制为256MB,但仍可检查
AndroidManifest.xml中android:largeHeap是否开启,以及针对目标SDK版本的Heap参数是否合理,不过此场景下更优先排查泄漏。
临时缓解方案
- 在
MainActivity的onDestroy方法中,手动调用navController.popBackStack(null, true)清空导航栈,释放相关资源。 - 应用进入后台时(
onPause/onStop),清理动态模块状态缓存,比如调用DynamicInstallManager的相关清理方法(若有)。
内容的提问来源于stack exchange,提问作者Long song soc
相关产品推荐
相关产品推荐

