应避免长生命周期对象强引用短生命周期对象,可通过局部代码块封装容器、weakreference/weakhashmap弱引用、生命周期钩子清理及kotlin作用域函数约束作用域来防止内存泄漏。

在长生命周期对象(如 Activity、ViewModel、Service 或单例类)中,直接持有短生命周期对象(如 View、Context、Fragment、Composable 函数引用等)的强引用,极易引发内存泄漏。普通代码块(即非静态、非匿名内部类、非 lambda 持久化)本身不具备生命周期,但它可以成为**安全持有与及时清理短生命周期对象容器的结构载体**——关键不在“块”的形式,而在于如何用它组织引用、限定作用域、主动解绑。
用普通代码块封装容器并控制作用域
将短生命周期对象统一放入局部声明的容器(如 List、Map、WeakHashMap),并在其所属的逻辑块内完成全部使用和清理,避免逃逸到类字段中:
- 在方法体内定义容器,只在该方法执行期间存在,方法返回后容器自动失效
- 不将容器声明为成员变量;若需跨方法协作,改用参数传递或回调通知,而非长期持有
- 示例:在 Activity 的某个业务方法中临时缓存一组 View 引用用于批量动画,执行完立即清空
用 WeakReference 容器替代强引用集合
当确实需要在长生命周期对象中暂存短生命周期对象(如监听器、回调、View),优先选用弱引用容器,让 GC 可自然回收:
- 用 WeakHashMap
存储以短生命周期对象为 key 的映射(如 WeakHashMap ) - 用 ArrayList
> 替代 ArrayList,访问前检查 get() 是否为 null - 避免使用 HashMap / ArrayList 直接持有 Activity、Fragment、Context 等强引用
在生命周期钩子中配对清理容器内容
即使用了普通代码块初始化容器,若容器被提升为成员变量,就必须在对应生命周期终点显式清空:
- Activity 中:在 onDestroy() 清空所有 WeakReference 列表、移除 Handler 回调、注销 BroadcastReceiver
- ViewModel 中:在 onCleared() 遍历容器,调用 remove() 或 clear(),尤其注意取消协程 Job、清理 Flow 收集器
- 自定义 Manager 类中:提供 destroy() 方法,并确保调用方(如 Fragment)在 onViewStateRestored 或 onDestroyView 后主动触发
用作用域函数约束容器生命周期(Kotlin 场景)
Kotlin 的 let/run/also 等作用域函数可天然形成代码块边界,配合局部变量进一步收窄引用存活时间:
- 用 view?.let { tempContainer.add(it) } 确保只在 view 非空时操作,且 tempContainer 是局部变量
- 避免 view?.run { this@Activity.callback = ::handleClick } —— 这会把 this@Activity 和 handleClick(绑定当前 Composable 上下文)一并捕获
- 对需异步使用的短生命周期对象,先提取必要数据(如 id、状态值),再传入后台线程,而非传递对象本身











