当前位置: 首页 > news >正文

【腾讯优测干货分享】Android内存泄漏的简单检查与分析方法

本文来自于Dev Club 开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57d14047603a5bf1242ad01b

导语

内存泄漏问题大约是Android开发者最烦恼的问题之一了,项目中连续遇到几个内存泄漏问题,这里简单总结下检查分析内存泄漏的一些工具与方法。

一、什么是内存泄漏?

大家都知道,java是有垃圾回收机制的,这使得java程序员比C++程序员轻松了许多,存储申请了,不用心心念念要加一句释放,java虚拟机会派出一些回收线程兢兢业业不定时地回收那些不再被需要的内存空间(注意回收的不是对象本身,而是对象占据的内存空间)。

Q1:什么叫不再被需要的内存空间?

答:Java没有指针,全凭引用来和对象进行关联,通过引用来操作对象。如果一个对象没有与任何引用关联,那么这个对象也就不太可能被使用到了,回收器便是把这些“无任何引用的对象”作为目标,回收了它们占据的内存空间。

Q2:如何分辨为对象无引用?

答:2种方法

  1. 引用计数法
    直接计数,简单高效,Python便是采用该方法。但是如果出现 两个对象相互引用,即使它们都无法被外界访问到,计数器不为0它们也始终不会被回收。为了解决该问题,java采用的是b方法。

  2. 可达性分析法
    这个方法设置了一系列的“GC Roots”对象作为索引起点,如果一个对象 与起点对象之间均无可达路径,那么这个不可达的对象就会成为回收对象。这种方法处理 两个对象相互引用的问题,如果两个对象均没有外部引用,会被判断为不可达对象进而被回收(如下图)。

Q3:有了回收机制,放心大胆用不会有内存泄漏?

答:答案当然是No!

虽然垃圾回收器会帮我们干掉大部分无用的内存空间,但是对于还保持着引用,但逻辑上已经不会再用到的对象,垃圾回收器不会回收它们。这些对象积累在内存中,直到程序结束,就是我们所说的“内存泄漏”。

当然了,用户对单次的内存泄漏并没有什么感知,但当泄漏积累到内存都被消耗完,就会导致卡顿,崩溃。

二、发现内存泄漏

内存泄漏不可小视,在Android开发中,比如说一个Activity页面会占用许多资源开销,如果页面发生泄漏,关闭以后页面没有能被系统回收,对应用程序的伤害是很大的。

Q1:在Android开发测试中一般如何发现内存泄漏的发生呢?

答:

方法1:反复操作观察内存变化

内存泄漏常见变现为程序使用时间越长,内存占用越多。那我们通过反复操作应用,比如反复点开/关闭页面,观察内存变化状况是否一点点上涨,可以粗略地判断是否有内存泄漏

1.通过 DDMS 中的 heap 工具,可以查看应用内存的使用情况

2.Android studio也可以方便查看

方法2:通过代码检测Activity泄漏

基本思路:

1)debug版本可以起一个长期工作的线程LeakThread在后台专门做泄漏检测

2)向Application注册一个 页面生命周期 的监听:application.registerActivityLifecycleCallbacks

3)在监听类中对 onActivityDestoryed(Activity activity) 的事件回调做处理:

如果一个Activity走到onDestroy,那么这个Activity对象就是需要被回收的目标。

我们声明一个检测对象的弱引用ref = new WeakReference

转载于:https://www.cnblogs.com/bugly/p/5864608.html

相关文章:

  • java集合框架学习—LinkedHashMap的实现原理
  • C#基础-MD5验证
  • java中Hashtable与HashMap的区别
  • html5使用FileReader上传图片
  • java中hashcode()和equals()的详解
  • ADO.NET完整增删改
  • Java精华积累:初学者都应该搞懂的问题
  • EasyUI——常见用法总结
  • 简单介绍Java语言中内存管理的几个技巧
  • java10-2 toString()方法
  • java六种异常处理的陋习
  • JAXB
  • 使用jdk1.5装箱及拆箱功能时注意的问题
  • 新手简单使用MQ查看消息图解
  • JAVA实用技巧:定时执行任务的三种方法
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • js中forEach回调同异步问题
  • Laravel Mix运行时关于es2015报错解决方案
  • mongodb--安装和初步使用教程
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • Tornado学习笔记(1)
  • Yii源码解读-服务定位器(Service Locator)
  • 解析 Webpack中import、require、按需加载的执行过程
  • 开源SQL-on-Hadoop系统一览
  • 免费小说阅读小程序
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 如何学习JavaEE,项目又该如何做?
  • 时间复杂度与空间复杂度分析
  • 如何正确理解,内页权重高于首页?
  • ​Spring Boot 分片上传文件
  • ​第20课 在Android Native开发中加入新的C++类
  • #HarmonyOS:软件安装window和mac预览Hello World
  • #每天一道面试题# 什么是MySQL的回表查询
  • (23)Linux的软硬连接
  • (31)对象的克隆
  • (39)STM32——FLASH闪存
  • (html5)在移动端input输入搜索项后 输入法下面为什么不想百度那样出现前往? 而我的出现的是换行...
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (二)fiber的基本认识
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (机器学习-深度学习快速入门)第三章机器学习-第二节:机器学习模型之线性回归
  • (十七)devops持续集成开发——使用jenkins流水线pipeline方式发布一个微服务项目
  • (转)h264中avc和flv数据的解析
  • (转载)PyTorch代码规范最佳实践和样式指南
  • .NET 设计模式—简单工厂(Simple Factory Pattern)
  • .NET 中各种混淆(Obfuscation)的含义、原理、实际效果和不同级别的差异(使用 SmartAssembly)
  • .NET/C# 使用 #if 和 Conditional 特性来按条件编译代码的不同原理和适用场景
  • @font-face 用字体画图标
  • @PreAuthorize注解
  • @Transaction注解失效的几种场景(附有示例代码)
  • [ 渗透工具篇 ] 一篇文章让你掌握神奇的shuize -- 信息收集自动化工具
  • [04] Android逐帧动画(一)