Android技术分享|Android 中部分内存泄漏示例及解决方案

 我来答
大沈他次苹0B
2022-07-14 · TA获得超过7322个赞
知道大有可为答主
回答量:3059
采纳率:100%
帮助的人:177万
展开全部

内存泄漏:

举例:

请注意以下的例子是虚构的

内存抖动

源自Android文档中的 Memory churn 一词,中文翻译为内存抖动。

指快速频繁的创建对象从而产生的性能问题。

引用Android文档原文:

Java内存泄漏的根本原因是 长生命周期 的对象持有 短生命周期 对象的引用就很可能发生内存泄漏。

尽管短生命周期对象已经不再需要,但因为长生命周期依旧持有它的引用,故不能被回收而导致内存泄漏。

静态集合类引起的内存泄漏


如果仅仅释放引用本身(tO = null), ArrayList 依然在引用该对象,GC无法回收。

监听器

在Java应用中,通常会用到很多监听器,一般通过 addXXXXListener() 实现。但释放对象时通常会忘记删除监听器,从而增加内存泄漏的风险。

各种连接

如数据库连接、网络连接(Socket)和I/O连接。忘记显式调用 close() 方法引起的内存泄漏。

内部类和外部模块的引用

内部类的引用是很容易被遗忘的一种,一旦没有释放可能会导致一系列后续对象无法释放。此外还要小心外部模块不经意的引用,内部类是否提供相应的操作去除外部引用。

单例模式

由于单例的静态特性,使其生命周期与应用的生命周期一样长,一旦使用不恰当极易造成内存泄漏。如果单利持有外部引用,需要注意提供释放方式,否则当外部对象无法被正常回收时,会进而导致内存泄漏。

集合类泄漏

如集合的使用范围超过逻辑代码的范围,需要格外注意删除机制是否完善可靠。比如由静态属性 static 指向的集合。

单利泄漏

以下为简单逻辑代码,只为举例说明内存泄漏问题,不保证单利模式的可靠性。


AppManager 创建时需要传入一个 Context ,这个 Context 的生命周期长短至关重要。

1. 如果传入的是 Application 的 Context ,因为 Application 的生命周期等同于应用的生命周期,所以没有任何问题。

2. 如果传入的是 Activity 的 Context ,则需要考虑这个 Activity 是否在整个生命周期都不会被回收了,如果不是,则会造成内存泄漏。

非静态内部类创建静态实例造成的内存泄漏


应该将该内部类单独封装为一个单例来使用。

匿名内部类/异步线程


Runnable都使用了匿名内部类,将持有MyActivity的引用。如果任务在Activity销毁前未完成,将导致Activity的内存无法被回收,从而造成内存泄漏。

解决方法:将Runnable独立出来或使用静态内部类,可以避免因持有外部对象导致的内存泄漏。

Handler造成的内存泄漏


Handler属于TLS(Thread Local Storage)变量,生命周期与Activity是不一致的,容易导致持有的对象无法正确被释放

当Android应用程序启动时,该应用程序的主线程会自动创建一个Looper对象和与之关联的MessageQueue。

当主线程中实例化一个Handler对象后,它就会自动与主线程Looper的MessageQueue关联起来。所有发送到MessageQueue的Messag都会持有Handler的引用,所以Looper会据此回调Handle的handleMessage()方法来处理消息。只要MessageQueue中有未处理的Message,Looper就会不断的从中取出并交给Handler处理。

另外,主线程的Looper对象会伴随该应用程序的整个生命周期。

在Java中,非静态内部类和匿名类内部类都会潜在持有它们所属的外部类的引用,但是静态内部类却不会。

当该 Activity 被 finish() 掉时,延迟执行任务的 Message 还会继续存在于主线程中,它持有该 Activity 的 Handler 引用,所以此时 finish() 掉的 Activity 就不会被回收了从而造成内存泄漏(因 Handler 为非静态内部类,它会持有外部类的引用,在这里就是指 SampleActivity)。


避免不必要的静态成员变量

对于BroadcastReceiver、ContentObserver、File、Cursor、Stream、Bitmap等资源的使用,应在Activity销毁前及时关闭或注销。

不使用WebView对象时,应调用`destroy()`方法销毁。

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
浙江启扬智能科技有限公司
2023-06-12 广告
Android和ARM、Linux之间存在密切的联系。Android是一种基于Linux内核的嵌入式智能操作系统,它采用了ARM处理器作为其主要处理器架构。Android的内核和许多应用程序都是基于ARM架构编写的,包括处理器和内存管理器。... 点击进入详情页
本回答由浙江启扬智能科技有限公司提供
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式