内存泄漏对每一位 Android 开发一定是司空见惯,大家或多或少都肯定有些许接触。大家都知道,每一个手机都有一定的承载上限,多处的内存泄漏堆积一定会堆积如山,最终出现内存爆炸 OOM。

而这,也是极有可能在 Android 面试中一道常见的开放题。

内存泄漏的根本原因是一个长生命周期的对象持有了一个短生命周期的对象。如果你对垃圾回收机制有所了解,我想这个问题基本难不住你,因为知道了原理,自然不会去触碰这些极易导致内存泄漏的雷区。

该题重在积累,不需要死记硬背,自己多总结即可。

1. 长生命周期对象持有 Activity

这基本是最常见的内存泄漏了,比如

  • 内部类形式使用 Handler 同时发送延时消息,或者在 Handler 里面执行耗时任务,在任务还没完成的时候 Activity 需要销毁。这时候由于 Handler 持有 Activity 的强引用导致 Activity 无法被回收。
  • 同理内部类形式的使用 AsyncTask 执行耗时任务也会导致内存泄漏的发生。
  • 单例作为最长生命周期的对象,自然不应该持有 Activity 从而导致内存泄漏发生;

针对上面这种情况,基本不必多说了,不要使用内部类或者匿名内部类做这样的处理就好了,实际上 IDE 也会弹出警告,我想大家应该还是都知道采用静态内部类或者在销毁页面的时候使用相关方法移除处理的。

Activity 中匿名使用 Handler 实际上会导致 Handler 内部类持有外部类的引用,而 SendMessage() 的时候 Message 会持有 HandlerenqueueMessage 机制又会导致 MeassageQueue 持有 Message。所以当发送的是延迟消息那么 Message 并不会立即的遍历出来处理而是阻塞到对应的 Message 触发时间以后再处理。那么阻塞的这段时间中页面销毁一定会造成内存泄漏。

2. 各种注册操作没有对应的反注册

这一点基本不必多说,相信大家刚刚开始学习广播和 Service 的时候一定对此有所接触,然后就是比如我们常用的第三方框架 EventBus 也是一样的。平时使用的时候注意在对应的生命周期方法中进行反注册。

3. Bitmap 使用完没有注意 recycle()

Bitmap 作为大对象,在使用完毕一定要注意调用 recycle() 进行回收。TypedArrayCursor、各种流同理,一定要在最后调用自己的回收关闭方法处理。

4. WebView 使用不当

WebView 是非常常用的控件,但稍有不注意也会导致内存泄漏。内存泄漏的场景: 很多人使用 Webview 都喜欢采用布局引用方式, 这其实也是作为内存泄漏的一个隐患。当 Activity 被关闭时,Webview 不会被 GC 马上回收,而是提交给事务,进行队列处理,这样就造成了内存泄漏, 导致 Webview 无法及时回收。

目前所知的比较安全的方案是:

  • 在布局中动态添加 WebView。
  • 采用下面的方法。
override fun onDestroy() {
webView?.apply {
val parent = parent
if (parent is ViewGroup) {
parent.removeView(this)
}
stopLoading()
// 退出时调用此方法,移除绑定的服务,否则某些特定系统会报错
settings.javaScriptEnabled = false
clearHistory()
removeAllViews()
destroy()
}
}

5. 循环引用

循环引用导致内存泄漏比较少见,正常来讲不会有人写出 A 持有 B,B 持有 C,C 又持有A 这样的代码,不过总还是需要注意。

总的来说,内存泄漏很常见,但检测方式也很多。我们的 Android Studio 自带的 Monitors 就可以帮我们找到大部分内存问题,当然我们也可以采用譬如 LeakCanary 这样的库去做检测。

每日一问:Android 中内存泄漏都有哪些注意点?的更多相关文章

  1. android性能测试内存泄漏

    1.什么是内存泄漏?     适用于该系统的内存使用内存泄漏,未回复(释放),该内存可以没有事业,也不能被其他人使用使用自己. 2.出有什么差别?    内存泄漏是分配出去的内存无法回收.    内存 ...

  2. 利用Android Studio、MAT对Android进行内存泄漏检测

    利用Android Studio.MAT对Android进行内存泄漏检测 Android开发中难免会遇到各种内存泄漏,如果不及时发现处理,会导致出现内存越用越大,可能会因为内存泄漏导致出现各种奇怪的c ...

  3. [轉]Android的内存泄漏和调试

    一. Android的内存机制 Android的程序由Java语言编写,所以Android的内存管理与Java的内存管理相似.程序员通过new为对象分配内存,所有对象在java堆内分配空间:然而对象的 ...

  4. Android防止内存泄漏以及MAT的使用

    Android发生内存泄漏最普遍的一种情况就是长期保持对Context,特别是Activity的引用,使得Activity无法被销毁.这也就意味着Activity中所有的成员变量也没办法销毁.本文仅介 ...

  5. android 常见内存泄漏原因及解决办法

    android常见内存泄漏主要有以下几类: 一.Handler 引起的内存泄漏. 在Android开发中,我们经常会使用Handler来控制主线程UI程序的界面变化,使用非常简单方便,但是稍不注意,很 ...

  6. [原理] Android Native内存泄漏检测原理解析

    转载请注明出处:https://www.cnblogs.com/zzcperf/articles/11615655.html 上一篇文章列举了不同版本Android OS内存泄漏的检测操作(传送门), ...

  7. C++中内存泄漏的检测方法介绍

    C++中内存泄漏的检测方法介绍 首先我们需要知道程序有没有内存泄露,然后定位到底是哪行代码出现内存泄露了,这样才能将其修复. 最简单的方法当然是借助于专业的检测工具,比较有名如BoundsCheck, ...

  8. [转]Android中内存占用的含义:(VSS,PSS,RSS,USS)

    Android中内存占用的含义:(VSS,PSS,RSS,USS) 作者: andforce 分类: 安卓系统 发布时间: 2013-09-07 00:03 ė1,915 浏览数 6没有评论 在eng ...

  9. Android开发常见的Activity中内存泄漏及解决办法

    上一篇文章楼主提到由Context引发的内存泄漏,在这一篇文章里,我们来谈谈Android开发中常见的Activity内存泄漏及解决办法.本文将会以“为什么”“怎么解决”的方式来介绍这几种内存泄漏. ...

随机推荐

  1. Prometheus 安装Alertmanager集成

    Prometheus 安装Alertmanager集成 # 下载地址 地址1:https://prometheus.io/download/ 地址2:https://github.com/promet ...

  2. Java中转换为二进制的几种实现

    public class HexUtil { private static final String[] DIGITS_UPPER = {"0", "1", & ...

  3. net core 记录自定义端口多个方式

    1.直接修改 . 2.代码定义 public class Program { public static void Main(string[] args) { CreateWebHostBuilder ...

  4. Regex 常见语法

    常用元字符 . 匹配除换行符以外的任意字符. \w 匹配字母或数字或下划线或汉字.\W 匹配任意不是字母,数字,下划线,汉字的字符. \s 匹配任意的空白符.\S 匹配任意不是空白符的字符.等价于 [ ...

  5. sql 按指定规则排序,例如 按 1,3,2排序 而不是1,2,3

    我们都知道 sql语句中的排序有desc(降序).asc(升序),这两个都是按顺序排列的,最近有一个需求是不按顺序排序了 ,抽出个别的排在前面,并且这种需求是应对的问题中的数据是比较少的,而且没有规律 ...

  6. Git 版本及版本范围表示法

    很多 Git 命令都使用 revision(修订版本)作为参数.根据不同的命令,有时候 revision 参 数代表一个特定的提交,有时候代表某一个提交可以追踪到的所有的父提交(比如 git log) ...

  7. 对比ubuntu与centos系统 ​​​​

    CentOS与Ubuntu该如何选择,哪个更好用.笔者在自媒体平台收集了一些网友的观点,较为经典,分享给大家.至于应该选择哪个,希望看完本文章后,读者心中有数. 观点1:CentOS适用于服务器,Ub ...

  8. 数据库系列(五)之 mysql的伸缩性

    这篇文章,主要讲述mysql的伸缩性.在国内mysql一直都是使用得最多的数据库,在国外也排名前三.mysql是一款开源的.性能较高的数据库. 伸缩性是指在软件设计中,软件(数据库.应用程序)通过特定 ...

  9. tcp 3次握手和4次挥手

    TCP标志位 (参考来源:https://blog.csdn.net/ltstud/article/details/73995933和 https://blog.csdn.net/weixin_308 ...

  10. VS Code如何在浏览器中打开Html文件?

    1.首先打开扩展 “ 文件 → 首选项 → 按键映射扩展” 快捷键:[ Ctrl+K Ctrl+M ] 2.在出现的窗口输入“open in browser”,安装 3.打开Html文件 Alt+B: ...