外观
Agent 长时间运行,怎样控制内存、功耗与后台任务?
标准回答
我会先测“持续运行后”发生了什么,而不只看刚启动时的指标。内存区分 Java 堆、Native、图片和模型运行时,观察重复进入退出、长对话、连续任务后的趋势;功耗则看 CPU 活动、网络、设备扫描、唤醒和模型持续计算。
内存上,我会限制聊天展示、缓存、排队任务和模型上下文的规模,检查监听器、回调、Handler 消息和长生命周期对象是否持有 Activity。模型和数据库等资源明确由哪个组件拥有、何时复用、何时关闭;不是所有增长都是泄漏,也不能只盯 Java heap 就忽略 Native 或图形资源。
功耗上,优先事件驱动,减少无意义轮询、反复重连和后台持续扫描。可以批量执行的工作合并执行,重试设置退避和上限,取消后及时停止传感器、流式连接和模型计算。确实需要 WakeLock 时限定范围并及时释放,不能把它当成常驻运行开关。
后台机制按任务性质选择:只服务当前页面的工作跟随页面取消;可延后且需要可靠调度的工作可考虑 WorkManager;符合系统要求、用户可感知的持续工作再评估前台服务及其类型和启动限制。系统应用是否豁免某些规则需逐项核对,不能默认进程永远存活。
关键机制
- 用相同脚本重复运行,区分正常缓存、短时峰值和持续泄漏。
- 每种资源有明确所有者、上限和释放时机;取消要传到真正消耗资源的层。
- 任务调度机制不等于线程机制,也不等于保证立即执行。
通俗例子
页面退出后仍在耗电:先看流式请求、扫描和推理是否真的停止,再查订阅是否解除。仅隐藏加载动画或清空 View,不会停止底层正在运行的任务。
追问与回答
怎样确认 Activity 泄漏?
我会重复进入退出页面,等待合理的回收时机,观察实例是否持续保留,再通过堆分析查看到 GC Root 的引用链。常见是单例、未注销监听器或延迟消息持有页面。找到引用链后修正生命周期和资源所有权,再重复同样操作验证;不能只凭内存曲线上升就判定泄漏。
想让 Agent 一直在线,直接上前台服务可以吗?
先要明确“在线”需要持续做什么。如果只是等待可延后任务,不必常驻计算;如果是用户主动开启的持续语音或连接任务,再检查对应前台服务类型、权限和启动条件,并提供可见状态与停止入口。无论采用哪种机制,都需要处理进程退出和任务恢复,不能承诺永不被杀。
易混淆点
WorkManager 不适合作为每个聊天增量的实时执行器;前台服务不是无限保活,系统应用身份也不是通用豁免。
参考资料
内容来源
- Android 技术札记 · 原条目
system-long-running