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

AutofillClientController致Activity内存泄漏:系统问题还是实现问题?

旋转模拟器导致ExampleActivity内存泄漏,求助排查思路

旋转模拟器时出现如下内存泄漏问题,无法明确根源,怀疑是系统的AutofillClientController导致ExampleActivity泄漏,恳请各位提供排查思路!

测试环境

  • Pixel 7 Pro API 34
  • Pixel 4 API 31
  • Pixel 3a API 28
  • Pixel 4 API 21(泄漏报告细节略有不同,但推测原因一致)
  • LeakCanary 2.13

LeakCanary泄漏分析报告

┬───
│ GC根:系统类
│
├─ android.provider.FontsContract 类
│    未泄漏:否(ExampleApplication↓ 未泄漏,且类永远不会泄漏)
│    ↓ 静态字段 FontsContract.sContext
├─ com.example.ExampleApplication 实例
│    未泄漏:否(Application是单例)
│    mBase 是 android.app.ContextImpl 的实例
│    ↓ Application.mLoadedApk
│                  ~~~~~~~~~~
├─ android.app.LoadedApk 实例
│    泄漏状态:未知
│    保留206.8 kB,涉及4052个对象
│    mApplication 是 com.example.ExampleApplication 的实例
│    接收器列表:
│    ..ExampleApplication@321728936
│    ....VisibilityTracker@329242680
│    ....aF@329242760
│    ....d@329242824
│    ....RF@329242896
│    ....ProxyChangeListener$ProxyReceiver@329242968
│    ↓ LoadedApk.mServices
│                ~~~~~~~~~
├─ android.util.ArrayMap 实例
│    泄漏状态:未知
│    保留203.2 kB,涉及4011个对象
│    ↓ ArrayMap.mArray
│               ~~~~~~
├─ java.lang.Object[] 数组
│    泄漏状态:未知
│    保留203.2 kB,涉及4009个对象
│    ↓ Object[2]
│            ~~~
├─ android.app.ContextImpl 实例
│    泄漏状态:未知
│    保留6.2 kB,涉及86个对象
│    mOuterContext 是 android.app.ContextImpl 的实例
│    ContextImpl.mOuterContext == ContextImpl.this:未绑定到任何特定生命周期
│    ↓ ContextImpl.mAutofillClient
│                  ~~~~~~~~~~~~~~~
├─ android.view.autofill.AutofillClientController 实例
│    泄漏状态:未知
│    保留26 B,涉及1个对象
│    mActivity 是 com.example.ui.ExampleActivity 的实例,且 mDestroyed = true
│    ↓ AutofillClientController.mActivity
│                               ~~~~~~~~~
╰→ com.example.ui.ExampleActivity 实例
​     泄漏状态:是(ObjectWatcher监测到该对象,因为com.example.ui.ExampleActivity已收到Activity#onDestroy()回调,且Activity#mDestroyed为true)
​     保留51.8 kB,涉及1004个对象
​     key = a1f4ff6a-48ea-4ba9-90c4-7f746b99af89
​     watchDurationMillis = 7757
​     retainedDurationMillis = 2755
​     mApplication 是 com.example.ExampleApplication 的实例
​     mBase 是 androidx.appcompat.view.ContextThemeWrapper 的实例

元数据

Build.VERSION.SDK_INT: 34
Build.MANUFACTURER: Google
LeakCanary版本: 2.13
应用进程名: com.example
类数量: 35752
实例数量: 351728
基本类型数组数量: 189083
对象数组数量: 44181
线程数量: 64
堆总字节数: 39264516
Bitmap数量: 35
Bitmap总字节数: 2247331
大Bitmap数量: 0
大Bitmap总字节数: 0
统计信息: LruCache[maxSize=3000,hits=166095,misses=321890,hitRate=34%]
RandomAccess[bytes=15827352,reads=321890,travel=107139495512,range=47678011,size=58241724]
分析耗时: 26210 ms

排查思路

  1. 核查Autofill相关逻辑

    • 检查ExampleActivity中是否主动启用Autofill功能,比如调用setAutofillHints()或自定义AutofillCallback,确保在onDestroy()中清理相关引用,取消注册回调。
    • 检查布局内EditText等控件是否设置了autofillHints属性,系统Autofill服务可能会持有这些控件所在Activity的引用。
  2. 禁用Autofill验证泄漏根源

    • 在测试设备手动关闭系统Autofill服务(设置→系统→语言和输入法→高级→自动填充服务),重新测试旋转场景,若泄漏消失则可确认是系统Autofill服务问题。
    • 也可在应用内临时禁用Autofill:在Activity的onCreate()中调用getWindow().getDecorView().setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS),验证泄漏是否缓解。
  3. 排查Context引用问题

    • 从泄漏链看,LoadedApk的mServices持有ContextImpl进而关联到AutofillClientController,检查应用内全局单例或静态对象是否意外持有Activity Context,而非Application Context。
    • 确认所有需Context的场景,比如注册广播接收器、初始化第三方库时,是否误用Activity Context,改用Application Context可避免生命周期绑定问题。
  4. 系统版本适配差异排查

    • 对比API 21与其他版本的泄漏链差异,确认是否是系统Autofill服务在不同版本的实现差异导致泄漏。
    • 查阅Android官方文档,确认对应版本Autofill相关API的行为变化,是否存在已知内存泄漏问题及官方修复方案。
  5. 进一步定位泄漏点

    • 使用Android Studio Profiler记录旋转前后的堆快照,对比Activity实例的引用链,找到更具体的泄漏路径。
    • 在ExampleActivity的onDestroy()中打印可能的引用持有者,或用弱引用跟踪哪些对象仍持有Activity引用。

内容的提问来源于stack exchange,提问作者Oscar Spruit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 15:54:49