Android 内存泄漏详解
一、什么是内存泄漏内存泄漏Memory Leak是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放造成系统内存的浪费导致程序运行速度减慢甚至系统崩溃等严重后果。在 Android 中更具体的定义是长生命周期对象持有短生命周期对象的引用导致短生命周期对象无法被垃圾回收器GC回收。二、内存泄漏的危害危害说明OOM 崩溃内存持续增长最终触发OutOfMemoryError应用崩溃卡顿/ANRGC 频繁触发主线程被阻塞界面卡顿甚至 ANR电量消耗后台泄漏导致进程无法被回收持续占用 CPU 和内存用户体验差应用越来越卡需要频繁重启三、导致内存泄漏的常见情况1.静态变量持有 Activity/Context 引用⭐最常见javapublic class Singleton { private static Singleton instance; private Context context; private Singleton(Context context) { this.context context; // ❌ 持有 Activity 引用 } public static Singleton getInstance(Context context) { if (instance null) { instance new Singleton(context); } return instance; } }原因静态变量生命周期 应用生命周期如果传入的是 Activity ContextActivity 销毁后仍被静态引用持有无法回收。解决使用Application Contextcontext.getApplicationContext()。2.非静态内部类 / 匿名内部类持有外部类引用javapublic class MainActivity extends AppCompatActivity { // ❌ 非静态内部类隐式持有外部 Activity 引用 private class MyHandler extends Handler { Override public void handleMessage(Message msg) { // ... } } // ❌ 匿名内部类同样持有 Activity 引用 private Runnable runnable new Runnable() { Override public void run() { // 延迟执行Activity 可能已销毁 } }; }原因非静态内部类会隐式持有外部类的引用。如果内部类有耗时操作如 Handler 延迟消息、AsyncTask、ThreadActivity 销毁时无法被回收。解决使用静态内部类弱引用WeakReference在onDestroy()中移除消息/回调javaprivate static class MyHandler extends Handler { private WeakReferenceMainActivity weakRef; MyHandler(MainActivity activity) { weakRef new WeakReference(activity); } Override public void handleMessage(Message msg) { MainActivity activity weakRef.get(); if (activity ! null) { // 安全使用 } } } Override protected void onDestroy() { super.onDestroy(); handler.removeCallbacksAndMessages(null); // 移除所有消息 }3.Handler 内存泄漏⭐高频考点javapublic class MainActivity extends AppCompatActivity { private Handler handler new Handler(Looper.getMainLooper()) { Override public void handleMessage(Message msg) { // 隐式持有 MainActivity 引用 } }; Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); handler.sendEmptyMessageDelayed(0, 10000); // 10秒后执行 } }原因Message会持有Handler引用Handler持有Activity引用MessageQueue持有Message。如果 Activity 在消息执行前被销毁整条引用链导致 Activity 泄漏。解决静态内部类 WeakReference onDestroy()移除消息。4.资源未关闭java// ❌ 未关闭的资源 Cursor cursor getContentResolver().query(...); // 忘记 cursor.close(); Bitmap bitmap BitmapFactory.decodeResource(...); // 忘记 bitmap.recycle(); // Android 3.0 后 Bitmap 内存由 GC 管理但大 Bitmap 仍建议及时释放 InputStream is ...; // 忘记 is.close();解决使用try-finally或在 Kotlin 中使用use自动关闭。5.监听器未注销javapublic class MainActivity extends AppCompatActivity { Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ❌ 注册后未在 onDestroy 中注销 getSystemService(LocationManager.class) .requestLocationUpdates(..., listener); } }常见场景LocationManager.requestLocationUpdates()未removeUpdates()SensorManager.registerListener()未unregisterListener()BroadcastReceiver动态注册后未unregisterReceiver()EventBus/RxJava订阅后未取消订阅解决在onDestroy()/onStop()中及时注销。6.单例模式持有回调/监听器javapublic class NetworkManager { private static NetworkManager instance; private NetworkCallback callback; public void setCallback(NetworkCallback callback) { this.callback callback; // ❌ 可能持有 Activity 引用 } }解决使用弱引用或在 Activity 销毁时手动置空。7.WebView 内存泄漏java// ❌ 直接在 xml 中声明 WebViewActivity 销毁时 WebView 持有 Activity 引用 WebView android:idid/webview android:layout_widthmatch_parent android:layout_heightmatch_parent /原因WebView 内部逻辑复杂会持有 Activity 引用且不易释放。解决使用独立的进程加载 WebViewandroid:process:web动态添加/移除 WebView销毁时从父布局移除并调用destroy()使用腾讯 X5 内核等第三方方案javaOverride protected void onDestroy() { if (webView ! null) { webView.loadDataWithBaseURL(null, , text/html, utf-8, null); webView.clearHistory(); ((ViewGroup) webView.getParent()).removeView(webView); webView.destroy(); webView null; } super.onDestroy(); }8.集合类泄漏javapublic class CacheManager { // ❌ 静态集合一直增长从未清理 private static ListObject cache new ArrayList(); public void add(Object obj) { cache.add(obj); } // 没有 remove() 或 clear() 机制 }解决使用LruCache等有限容量的缓存或设置过期清理机制。9.属性动画Animator未取消javaObjectAnimator animator ObjectAnimator.ofFloat(view, alpha, 0, 1); animator.setDuration(3000); animator.start(); // ❌ Activity 销毁时未取消动画原因动画会持有 target View 的引用View 持有 Activity 引用。解决在onDestroy()中animator.cancel()。10.系统服务持有 Contextjava// ❌ 错误 InputMethodManager imm (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);某些系统服务如InputMethodManager内部存在已知的内存泄漏 BugAndroid 底层问题。解决使用 Application Context 获取系统服务。11.第三方库使用不当Glide传入 Activity Context 时Glide 会绑定生命周期但如果传入 Application Context 且未手动管理可能泄漏RxJava订阅后未在onDestroy()中dispose()EventBus注册后未unregister()LeakCanary虽然它是检测工具但本身也可能有轻微影响四、内存泄漏检测工具表格工具用途LeakCanarySquare 出品自动检测并展示泄漏引用链开发必备Android Studio Profiler实时查看内存分配Heap Dump 分析MAT (Memory Analyzer Tool)分析 hprof 文件查找支配树和引用链adb shell dumpsys meminfo查看应用内存占用情况五、预防内存泄漏的黄金法则能用 Application Context 就不用 Activity Context静态变量不持有短生命周期对象内部类尽量声明为 static配合 WeakReference有注册就有注销有开启就有关闭耗时操作/延迟任务要考虑生命周期使用 Jetpack 组件ViewModel、Lifecycle、LiveData自动管理生命周期接入 LeakCanary 在开发阶段及时发现六、总结图plain长生命周期对象 ──持有引用──► 短生命周期对象 ↑ │ └───────────────────────────┘ 无法被 GC 回收 内存泄漏

相关新闻

C语言字符串函数进阶:安全版函数 + 错误处理 + 子串查找

C语言字符串函数进阶:安全版函数 + 错误处理 + 子串查找

适用对象:学过 strcpy / strcat / strcmp 的同学 本章目标:掌握安全版字符串函数 strstr 子串查找 strerror 错误处理引入:strcpy 为什么会让人又爱又恨? 上一章我们学了 strcpy,它简单粗暴,复制速度也快…

2026/10/18 4:43:19 阅读更多 →
多模态LLM实战:从CLIP视觉编码到信息融合的Wiki技能构建

多模态LLM实战:从CLIP视觉编码到信息融合的Wiki技能构建

1. 项目概述:当大语言模型“睁开双眼”最近在折腾一个挺有意思的东西,我把它叫做“多模态 LLM Wiki Skill”。简单来说,就是给一个大型语言模型(LLM)——比如我们熟悉的 Claude 或者 GPT——装上“眼睛”和“耳朵”&am…

2026/10/17 23:52:27 阅读更多 →
android Handler , Looper , Message , MessageQueue 详解

android Handler , Looper , Message , MessageQueue 详解

一、基础Q1:请简述 Handler 机制的工作原理核心回答:Handler 发送消息 → MessageQueue 按时间排序存储 → Looper 无限循环取出 → 回调 Handler 处理。细节:MessageQueue 不是队列,是单向链表,按 when(触…

2026/10/15 14:33:19 阅读更多 →

最新新闻

AI搜索优化实战:从语义理解到结构化数据提升引用率

AI搜索优化实战:从语义理解到结构化数据提升引用率

1. 算法流转弯了:为什么传统SEO打法在AI搜索里集体失灵先说一个我近期印象特别深的场景。某电商平台的运营同学跑来问我:他们有一批核心产品词,之前在某搜索引擎里稳稳占着首页前三,点击稳定得能当日报表看。可这两三个月&#xf…

2026/10/18 19:06:12 阅读更多 →
开源智能体OpenClaw落地物业:从AI客服到自动化工单处理

开源智能体OpenClaw落地物业:从AI客服到自动化工单处理

如果去年有人跟我说,程序员圈子里的开源AI智能体能被物业行业叫成“龙虾”,我肯定当段子听。但2026年开年,我在好几个物业项目的交流群里频繁看到同一个词:OpenClaw。这名字直译过来是“张开的钳子”,中文社区叫顺口了…

2026/10/18 19:06:12 阅读更多 →
元学习实战:提升模型迁移能力的架构设计与优化全记录

元学习实战:提升模型迁移能力的架构设计与优化全记录

不少做AI架构的朋友都会遇到同一个尴尬局面:模型在训练集上表现惊艳,一换到新的业务场景、新的数据分布,效果立刻跳水。调参数、加数据、换网络结构,折腾一圈下来,迁移效果还是不理想。我在多个项目里反复踩过这个坑之…

2026/10/18 19:06:12 阅读更多 →
多模态大模型驱动:AI Agent与具身智能的全自动研发落地实践

多模态大模型驱动:AI Agent与具身智能的全自动研发落地实践

这几年一直在研发效率工具这条线上折腾的人,应该都会有一种很微妙的体感:各种自动化工具堆了一堆,AI 编码助手也换了好几轮,可整个研发链路依然要靠大量人工去粘合。最近“社区说”里反复冒出来一个组合词,AI Agent、具…

2026/10/18 19:06:12 阅读更多 →
4款AI论文写作工具流水线实操:从搭框架到参考文献格式全流程指南

4款AI论文写作工具流水线实操:从搭框架到参考文献格式全流程指南

写论文这件事,拦路虎从来不是“没想法”,而是“憋不出来”。框架理不清、语言不学术、文献翻到眼花、参考文献格式改到崩溃——我刚带完一个模拟项目组,组里七八个学生全卡在这几关。后来我把4款AI论文写作工具按“搭骨架、填血肉、调语言、查…

2026/10/18 19:06:12 阅读更多 →
C#开发Modbus RTU串口调试工具:从协议解析到CRC校验全流程实战

C#开发Modbus RTU串口调试工具:从协议解析到CRC校验全流程实战

最近在调试一台现场仪表,厂家给的调试软件只能读不能写,而且界面汉化得乱七八糟,参数表里的寄存器地址还得对着文档一项项换算,烦得不行。干脆用C#在Visual Studio里自己写了个Modbus RTU主站调试工具,从串口收发到报文…

2026/10/18 19:05:12 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →