Android内存泄露和GC机制

    本文先对Android内存垃圾回收机制进行介绍,之后对分析、定位内存泄露常用的测试方法进行总结,分享给大家。

一、Android内存垃圾回收(GC机制)
1、综述
Android 应用中默认有三个线程:“main”主线程、GC线程、和Heap线程,而且在GC线程运行的过程中,主线程会中断执行。Java程序与C/C++等原生程序的一个不同点就是,Java虚拟机在运行Java程序的过程中,可以自动回收不再使用的对象实例,从而避免了程序员人工管理内存的繁琐工作。如果设备是单核CPU设备,一次只能运行一个线程,因此在GC线程运行的时候,必须中断主线程。但是如果设备上有多核CPU,即主线程可以和GC线程同时运行,在这种情况下执行GC,会不会中断主线程呢?答案是会的。
虽然有不同的内存垃圾回收实现算法,但有些算法需要中断其他Java线程的执行,如果中断的时间过长,给用户的感觉就是应用的响应速度变的越来越慢,甚至有可能出现ANR错误。

二、Android内存管理原理
1、垃圾内存回收算法
常见的垃圾回收算法引用计数法、标注并清理、拷贝、逐代回收,其中android系统采用的是标注并清理和拷贝GC,并不是大多数JVM实现中采用的逐代回收算法。在很多垃圾回收实现中,常常可以看到将几种算法合并使用的场景。

2、Logcat中的GC信息
Logcat中GC输出的信息格式如下:
Dalvik虚拟机的Log信息
D/dalvikvm( 9050): GC_CONCURRENT freed2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms

它们大致可以分成如下几个部分:
D/dalvikvm: <GC_Reason> <Amount_freed>, <Heap_stats>,
<External_memory_stats>, <Pause_time>

[GC的原因][回收的内存总量][GC堆内存的统计信息][外部内存的统计信息][中断时间]
各个字段的含义如下:
(1)、GC的原因,也就是GC类别,可分为:
a、GC_FOR_MALLOC 表示内存垃圾回收过程是因为在分配内存空间如(创建对象)时,内存不够而引发的。系统会杀死应用的进程并且回收所有内存。
b、GC_CONCURRENT 表明GC是在内存使用率达到一定的警戒线时,自动触发的。
c、GC_EXPLICIT 表明GC是被显式请求触发的。
d、GC_EXTERNAL_ALLOC在API版本10(Android3.0)以下的时候的垃圾回收机制。3.0以上版本所有的内存都在Dalvik堆中分配。它是用来回收dalvik虚拟机以外的内存(例如Bitmap中的内存或者NIObuffer中的内存)。
e、GC_HPROF_DUMP_HEAP 当请求生成HPROF文件来分析内存的时候会触发此类垃圾回收

(2)、回收的内存总量

(3)、回收后GC内存对的统计信息
堆中可用空间所占的百分比和(堆中对象的数量)/(堆的大小)

(4)、外部内存的统计信息
系统API版本10以下的系统中,Dalvik虚拟机堆外(分配的内存)/(限制的内存量)

(5)、GC造成的应用其他线程中断的时间
Concurrent类型的垃圾回收有两次暂停时间:一次发生在开始,另一次发生在结束。堆的内容越多,暂停的时间越长。
观察这些Log信息,如果heapstats中的数值(堆中对象数量)/(堆的大小)越来越大,那么应用中很有可能存在内存泄漏。

(6)、总结
一般根据下面两个线索判断应用是否存在内存泄露问题
1、应用运行一段时间后,因为内部抛出java.lang.OutOfMemoryError异常而崩溃;
2、在logcat中看到频繁的GC信息;

三、内存泄露
1、什么是内存泄漏
对于不同的语言平台来说,进行标记回收内存的算法是不一样的,像Android(Java)则采用GC-Root的标记回收算法。下图(Google 2011的IO大会)展示了Android内存的回收管理策略。

图中的每个圆节点代表对象的内存资源,箭头代表可达路径。当圆节点与GC Roots存在可达路径时,表示当前资源正被引用,虚拟机是无法对其进行回收的(如图中的黄色节点)。反过来,如果圆节点与GC Roots不存在可达路径,则意味着这块对象的内存资源不再被程序引用,系统虚拟机可以在GC过程中将其回收掉。
有了上面的内存回收的栗子,那么接下来就可以说说什么是内存泄漏了。

    从定义上讲,Android(Java)平台的内存泄漏是指没有用的对象资源任与GC-Root保持可达路径,导致系统无法进行回收。举一个最简单的栗子,我们在Activity的onCreate函数中注册一个广播接收者,但是在onDestory函数中并没有执行反注册,当Activity被finish掉时,Activity对象已经走完了自身的生命周期,应该被资源回收释放掉,但由于没有反注册,此时Activity和GC-Root间仍然有可达路径存在,导致Activity虽然被销毁,但是所占用的内存资源却无法被回收掉。

2、泄漏的源头
这里,将其归位以下三类:
(1)、自身编码引起
由项目开发人员自身的编码造成。
(2)、 第三方代码引起
这里的第三方代码包含两类:第三方非开源的SDK和开源的第三方框架。
(3)、系统原因
由Android系统自身造成的泄漏,如像WebView、InputMethodManager等引起的问题,还有某些第三方ROM存在的问题。
3.3泄漏的定位

  内存泄漏不像闪退的BUG,排查起来相对要比较困难些,比较极端的情况是当应用OOM了才发现存在内存泄漏问题,对用户影响太大。为此,我们希望在测试过程中能够尽早发现问题。下面介绍几种分析内存泄露问题的工具、方法。

3、静态代码分析工具 —— Lint
Lint是 Android Studio自带的工具,使用姿势很简单Analyze -> Inspect Code然后选择想要扫面的区域即可。


对可能引起泄漏的编码,Lint都会进行温馨提示。

关于Lint,大家可以自行拓展学习。

4、Android Memory Monitor
Android Studio提供的工具,用于监控应用的内存使用状态,在开发中也是非常实用的工具,可以用来打印出内存的状态信息。

打印获得的内存信息如下,可以通过右上角的绿色三角形按钮去分析泄漏的Activity和一些重复的字符串,目前只支持这两个,希望Google后面能够加入更多可选分析规则。

5、adb shell 命令
使用 adb shell dumpsys meminfo [PackageName],可以打印出指定包名的应用内存信息。

使用该命令可以很直观的观察到Activity的泄漏问题,是平常分析比较常用的一种方式。除了使用命令外,Android Studio也提供了下面的功能,和使用命令是一样效果的。

以上就是我在做内存泄漏定位分析的时候会用到的工具和方法,通常都是结合起来用,使用多个工具互补分析问题可以提高我们的效率和最终取得的效果。

生活不易,兼职赚点钱,谢谢关注的朋友支持
下载“”蜜源“”免费app领京东天猫优惠券,既省钱,又可以赚钱,(平台会付给我激活费3元每人,激活后,你也可以邀请其他人赚激活费):
Step 1: 应用宝或者苹果商店下载“蜜源”,这样下载比较安全,经过平台的病毒等检测
Setp 2: 使用手机注册后,需要激活码激活,输入 FaIlFA 激活即可
不懂得,可以私信聊

Android内存泄露和GC机制相关推荐

  1. 浅谈 JVM 内存结构及 GC 机制

    前言 JAVA GC(Garbage Collection,垃圾回收)机制是区别C++的一个重要特征,C++需要开发者自己实现垃圾回收的逻辑,而JAVA开发者则只需要专注于业务开发,因为垃圾回收这件繁 ...

  2. Android内存泄露测试不再蓝瘦,香菇

    在进行Android内存泄露分析时,面对成千上万个对象,你是否蓝瘦,香菇?作为测试人员你在进行内存泄露测试之后,是否有勇气告诉开发同事程序已经没有内存泄露,可以放心发布了? 众所周知,内存泄露测试难点 ...

  3. 深入Android内存泄露

    深入内存泄露 android应用层的内存泄露,其实就是java虚拟机的内存泄漏. (这里,暂不讨论C/C++本地内存的堆泄漏) 1.知识储备 1.Java内存模型 相关内存对象模型,参照博客精讲Jav ...

  4. Android内存泄露总结

    内存泄露是如何产生的? 当一个对象已经不需要再使用了,本该被回收时,而有另外一个正在使用的对象持有它的引用从而导致它不能被回收,这导致本该被回收的对象不能被回收而停留在堆内存中,这就产生了内存泄漏. ...

  5. JVM内存管理概述与android内存泄露分析

    一.内存划分 将内存划分为六大部分,分别是PC寄存器.JAVA虚拟机栈.JAVA堆.方法区.运行时常量池以及本地方法栈. 1.PC寄存器(线程独有):全称是程序计数寄存器,它记载着每一个线程当前运行的 ...

  6. Android 内存泄露

    1.定义 Android (或 JVM)的内存泄露:短⽣命周期的对象被⻓⽣命周期的对象持有,从⽽导致短⽣命周期的对象不能被释放 2.垃圾回收机制 垃圾回收机制分为「引⽤计数法」和「可达性分析法」: 「 ...

  7. Android 内存泄露分析

    1 内存泄漏简介 内存泄漏是指内存空间使用完毕后无法被释放的现象.尽管Java有垃圾回收机制(GC),但是对于还保持着引用,逻辑上却已经不会再用到的对象,垃圾回收器不会回收它们. 内存泄漏带来的危害: ...

  8. Android内存泄露抓取工具leakcanary

    引言 "A small leak will sink a great ship." - Benjamin Franklin 概述 某些对象的生命周期有限,当它们的工作完成以后,将会 ...

  9. android内存泄漏检测,Android内存泄露检测之LeakCanary的使用

    开始使用 目前为止最新的版本是2.3版本,相比于2.0之前的版本,2.0之后的版本在使用上简洁了很多,只需要在dependencies中加入LeakCanary的依赖即可.而且debugImpleme ...

最新文章

  1. APP检测软件更新逻辑
  2. 有道算法题--排序之桶排序实现求排序后相邻最大差值问题
  3. Sql Server实用操作-存储过程精解
  4. 学写网站(一)前端配置之安装nvm、node、npm
  5. 第十三节、SURF特征提取算法
  6. Educational Codeforces Round 94 (Rated for Div. 2)
  7. CentOS Linux 下的 vim 无法使用系统剪贴板,怎么解决呢?
  8. 西电计算机科学院实践中心,计算机基础教学实验中心
  9. Emlog博客MetBlogm主题-博客开源主题源码
  10. iosalipay_iOS支付宝支付主要代码
  11. c#利用zlib.net对文件进行deflate流压缩(和java程序压缩生成一样)
  12. 如何进行时间序列的特征工程?
  13. 创建数组-直接法/增量法 namelengthmax isvarname iskeyword
  14. SQL Server 2008 存储结构之DCM、BCM
  15. python实战篇(七)---一寸照换背景
  16. 快恢复二极管工作原理及使用
  17. Cloudera Manager 理论
  18. 教你几招!做客服怎么应对物流太慢的问题
  19. MacOS更新BigSur后git不可用的问题
  20. springboot拦截器Interceptor

热门文章

  1. mac设置隐藏文件可见
  2. 《HTTP权威指南》第十三章学习总结--摘要认证
  3. 王者荣耀苹果安卓不显示服务器,王者荣耀苹果、安卓用户换机之后数据全无,解决办法来了?...
  4. 高德地图 JS API 加载多个插件
  5. 极速office(Word)怎么在空白处添加下划线
  6. 爬虫Task 02 re
  7. 微信的这几个实用功能,你知道吗?
  8. UNIAPP点击动画 animation 点击动效
  9. 思科:99% 手机恶意软件针对 Android
  10. 64位系统运行报错:1%不是有效的win32应用程序解决