You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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工具自动检测内存泄漏,重点关注导航相关对象的泄漏路径。
  • 升级依赖版本:当前使用的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 09:14:57