当前位置:首页 > 娱乐 > android内存泄漏

android内存泄漏

2026-10-17 05:37:02 [时尚] 来源:力不从心网

刚跑完一个压力测试,存泄App 在后台挂了 20 分钟,存泄回来直接白屏。存泄Logcat 里一串 GC 日志,存泄堆内存从 64M 一路涨到 256M,存泄最后 OOM。存泄不用查了,存泄内存泄漏。存泄

Android 的存泄内存泄漏跟 C++ 那种不一样。C++ 是存泄 malloc 了没 free,明明白白。存泄Android 是存泄 GC 觉得这对象还有人用,不敢收,存泄实际上早该死了。存泄GC 的存泄垃圾回收机制是基于可达性分析的,从 GC Roots 出发,凡是还能被引用到的对象就不会被回收。问题就出在这个“还能被引用到”上。

最常见的场景:一个 Activity 被 finish 了,但某个静态变量或者单例还持有它的引用。GC 一看,哟,还有人牵着,不收。于是整个 Activity 连带它里面的 View 树、Bitmap、Context,全卡在堆里。一个 Activity 少说占几 M,来回旋转屏幕几次,堆就爆了。

我见过最离谱的一个案例。某项目里有个静态的 List<Callback>,每次 Activity 创建时就把自己注册进去,onDestroy 的时候忘了移除。用户正常使用,打开关闭同一个页面十几次,堆里就躺了十几个 Activity 实例。用 MAT 打开 hprof 文件一看,Dominator Tree 里那个 List 下面挂了一长串,跟葡萄似的。

LeakCanary 是必备工具。集成进去,debug 包跑起来,泄漏了直接通知栏弹出来,引用链给你列得清清楚楚。但有个坑:LeakCanary 只能检测 Activity 和 Fragment 的泄漏,其他对象它不管。而且有些泄漏是系统框架层的,比如 InputMethodManager 在某些版本上会持有 View 的引用,这种你改不了,只能绕。

Handler 也是重灾区。非静态内部类或者匿名类会隐式持有外部类的引用。你写个 Handler 做延时任务,延时 10 分钟,用户 2 分钟就退了页面。MessageQueue 里的 Message 还持有 Handler,Handler 持有 Activity,GC 干瞪眼。解决办法要么用静态内部类加 WeakReference,要么在 onDestroy 里 removeCallbacksAndMessages(null)。我倾向于后者,简单粗暴。

单例模式听起来人畜无害,实际上经常出事。比如一个 AppManager 单例,里面存了个 currentActivity 的引用。Activity 切换的时候没更新,旧的 Activity 就一直被单例攥着。还有 EventBus 这种,注册了没反注册,或者反注册写在了 onDestroy 里但 onDestroy 根本没被调用——比如 Activity 被系统回收了。

匿名内部类做回调也是经典陷阱。比如开个线程做网络请求,回调里更新 UI,匿名 Runnable 持有 Activity 引用。请求还没回来,Activity 先没了。线程还在跑,引用还在,内存就漏了。这种用 WeakReference 包一层,或者用 RxJava 的 CompositeDisposable 统一管理,onDestroy 的时候 dispose 掉。

资源没关也算。Cursor、File、Stream,用完不 close,底层 native 内存泄漏,Java 堆看着正常,native 堆一直涨。这种用 try-with-resources 或者 finally 里关,别偷懒。

说白了,内存泄漏的本质就是生命周期对不上。长生命周期的对象持有了短生命周期对象的引用,短的那个该走的时候走不了。写代码的时候多想想:这个引用,谁持有了它,持有者能活多久,被持有者该活多久。想清楚了,大部分泄漏都能避免。

MAT 和 LeakCanary 是事后排查,真正省事的办法是写的时候就注意。静态变量、单例、Handler、匿名内部类、资源对象,这几个地方多留个心眼。代码 review 的时候看到 static 修饰的集合或者 Context,直接问一句:这里会不会泄漏?

(责任编辑:休闲)

推荐文章
  • 多个网站无法同时运行的原因

    多个网站无法同时运行的原因 打开电脑,一口气点了五个浏览器窗口,结果三个网站转圈圈,两个直接报错“无法连接”。这事儿太常见了,但大多数人第一反应是骂网速——真不是网速的锅。 我自己的电脑就出过这毛病。一边开着视频会议,一边挂着网 ...[详细]
  • sql之父鱼皮数据网站

    sql之父鱼皮数据网站 ```html sql之父鱼皮数据网站 1995年,一个叫“鱼皮”的ID在某个BBS上发了张帖子,标题是《关系模型查询语言的实现草稿》。没人回。三天后他自己顶了一楼,贴出十几行SQL雏形, ...[详细]
  • itss信息技术服务运行维护等级就是运维

    itss信息技术服务运行维护等级就是运维 ITSS信息技术服务运行维护等级,说白了就是运维的国标认证。很多人第一次听到这个词,以为是某种高深的国际技术标准,其实它由中国电子工业标准化技术协会搞出来的,专门给国内IT运维服务定规矩。你公司做系统 ...[详细]
  • 洛克菲勤第一封信读后有感

    洛克菲勤第一封信读后有感 读完洛克菲勒写给儿子的第一封信,我脑子里反复转着一个细节:他16岁当簿记员时,每天只赚50美分,却坚持从这笔微薄收入里抠出5%存起来。这不是什么理财鸡汤,他后来在信里跟儿子说得很直白——那点钱根本不算 ...[详细]
  • fiddler官网下载地址

    fiddler官网下载地址 fiddler的官网下载地址是www.telerik.com/fiddler。这个地址我闭着眼都能打出来,因为过去十年里,我至少帮人找过二十次这个工具。 别急着点进去,先说说为什么非要官网。网上那 ...[详细]
  • cmd黑客简单攻击命令

    cmd黑客简单攻击命令 很多人对“黑客攻击”的想象来自电影——黑屏上绿色字符飞速滚动,敲几下键盘就能攻破五角大楼。现实里,Windows 自带的 cmd 确实能做一些事,但离“入侵”差得远。不过,有些命令组合确实可以被用来搞 ...[详细]
  • 小学音乐德育渗透的实践研究的阶段性成果

    小学音乐德育渗透的实践研究的阶段性成果 去年秋天,我在三年级的一节音乐课上教《我的祖国》。原本设计的是让学生感受旋律的优美,结果刚放完前奏,后排一个男孩突然举手:“老师,这首歌是不是讲我们国家的?”我愣了一下,顺势问他从哪听出来的。他说:“ ...[详细]
  • 石家庄市油漆厂快完蛋

    石家庄市油漆厂快完蛋 ```html 石家庄市油漆厂快完蛋了 厂门口那条水泥路裂得像龟壳,缝里长满灰绿的野草,半人高。门卫室窗户缺了两块玻璃,用化肥袋子堵着,风一吹就呼啦呼啦响。老赵坐在里头刷手机,刷到招聘信息就多看两眼 ...[详细]
  • 工具图片素材大全

    工具图片素材大全 我电脑里存着超过两万张工具图片。螺丝刀、扳手、电钻、锤子——不是那种产品渲染图,而是带锈迹、带划痕、带使用痕迹的真实工具。这些图片最初的用途很朴素:写维修教程时配图用。但后来我发现,它们成了另一种东西 ...[详细]
  • 宇宙黑洞真实视频

    宇宙黑洞真实视频 ```html 宇宙黑洞真实视频 body { background-color: #0a0a12; color: #d8d8e0; font-family: 'Georgia', 'Tim ...[详细]
热点阅读