内存泄漏改进方案及代码修改
1. 内存泄漏类型
本次内存优化,发现如下内存泄漏类型:
-
Bitmap未即时释放
-
Handler泄漏
-
static成员泄漏
-
Callback泄漏
-
Activity leak window
-
cursor未关闭
内存泄漏问题详细描述,参见《内存优化评估文档》。
下面将描述不同内存泄漏类型的解决方案。
2. 内存泄漏解决方案
2.1 Bitmap未即时释放
2.1.1泄漏原因
业务代码没有及时主动释放Bitmap,容易造成短时间内内存被大量占用,进一步诱发OOM的发生。
2.1.2解决方案
解决方案思路有两种情况:
1) 对于从文件系统加载、Drawable资源加载,建立二级缓存管理该类Btimap;
2) 对于内存创建、图形变换产生的Bitmap,由业务自己去即时释放资源。
ImageUtis、BitmapUtils封装了Bitmap加载/获取的二级缓存机制,加载文件系统的Bitmap,推荐使用ImageUtils中的getBitmap系列方法。
2.1.3实例
-
调用ImageUtis获取Bitmap
图1描述了使用二级缓存管理Bitmap。
图1使用二级缓存管理Bitmap
-
自行管理Bitmap
图2描述了自行管理Bitmap释放。
图2自行管理Bitmap释放
2.2 Handler泄漏
2.2.1泄漏原因
Handler泄漏的原因,大多是匿名构建Handler实例,从而持有外部类Activity实例导致。
2.2.2解决方案
解决方案思路有两种:
1)去除Handler实例持有的外部类引用,该类思路的做法,一般是将Handler的子类定义为静态内部类,或者以一个单独的类文件形式存在;
2)保证在Activity/Service退出时,清空消息队列中与Handler有关的所有消息。
推荐使用第一种思路,实现起来简单、高效,第二种思路虽也可实现,但要考虑的面比较多,容易产生遗漏。
2.2.3实例
图3描述了MyCellLayout.java文件中,有一个Handler泄漏实例。
图3 Handler泄漏实例
图4中所示代码对图3中的Handler泄漏做了修复。
图4 图3 Handler泄漏修复
2.3 static成员泄漏
2.3.1泄漏原因
Static类成员,其生命周期与App生命周期近乎等长,在不合理的设计中,static类成员持有的对象,其内部持有Activity实例等导致。
2.3.2解决方案
解决方案思路有两种:
5)在static类成员持有的对象内部, 规避持有Activity实例;
6)避免使用static成员。
2.3.3实例
图5描述了 GlobalMsgProcessHelper.java中static类成员泄漏。
图5 static类成员泄漏
图6是对图5 static类成员泄漏的修复。
图6 图5 static类成员泄漏修复
2.3 Callback泄漏
2.4.1泄漏原因
Callback直接或间接持有Activity实例等导致。
2.4.2解决方案
解决方案思路,在Callback对象内部规避持有Activity实例。
2.4.3实例
参见DeviceCategoryView.java DeviceCategoryDownloadCallback。
2.5 Activity leak window
2.5.1泄漏原因
Activity异外先于Dialog退出,导致本异常抛出,本质也是一种内存泄漏。
2.5.2解决方案
构建BaseDialog,使所有自定义Dialog均扩展自此类,在BaseDialog内部实现在Activity退出前先行销毁的逻辑。
2.5.3实例
图7 描述了BaseDialog实现自释放逻辑。
图8 描述了CommonDialog派生自BaseDialog
图7 BaseDialog实现自释放逻辑
图8 CommonDialog派生自BaseDialog
2.6 cursor未关闭
2.6.1泄漏原因
Cursor使用完后等导致。
2.6.2解决方案
解决方案思路,在Cursor使用完后释放资源。
2.6.3实例
图9描述了Cursor泄漏修复。
图9 Cursor泄漏修复
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人