一、了解内存泄漏概念
内存泄漏(Memory leak):
程序在向系统申请分配内存空间后(new),在使用完毕后未释放。结果导致一直占据该内存单元,我们和程序都无法在使用该内存单元,直到程序结束,这是内存泄漏。
内存溢出(out of memory):
程序向系统申请的内存空间超出了系统能给的,比如一车最多能坐5个人,你却非要塞下10个,车就挤爆了。
注意:大量的内存泄漏会导致内存溢出,因为内存出现泄漏,则内存得不到释放,系统分配的内存越来越少,最后导致溢出。
二、内存泄漏原理
内存:
JAVA 是在JVM 所虚拟出的内存环境中运行的,JVM的内存可分为三个区,堆(heap),栈(stack)和方法去(method)。
栈(stack):
是简单的数据结构,但在计算机中使用广泛,栈最显著的特征是:LIFO (后进先出),栈中只存在基本类型和对象的引用(不是对象)
堆(heap):
堆内存用于存放有new创建的对象和数组。在堆中分配的内存,由java虚拟机自动垃圾回收器(GC)来管理,jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身。
方法区(method):
又叫静态区,跟堆一样,被所有的线程共享,方法区包含所有的static变量
GC(垃圾回收器)原理:
垃圾回收(garbage collection,简称GC)可以自动清空堆中不再使用的对象。在JAVA中对象是通过引用使用的。如果再没有引用指向该对象,那么该对象就无法处理或调用该对象,这样的对象称为 不可到达(UNreachable)。垃圾回收用于释放不可到达的对象所占据的内存。忐忑的豌豆的程序想要分配的内存大于当前你的可用内存,才会触发GC机制。
图中 Obj4 和Obj 5 就属于不可到达对象,图中Obj 6 被global(全局变量,静态变量,生存期为这个程序)调用,所以Obj 6 在整个过程汇中不能被GC回收,会导致内存泄漏。
三、实战掌握入门泄漏如何测试
1、使用Android studio,连接上adb,使用Monitors可以监控到。
2、实际工作中,叫开发将 leakcanary 集成到软件中。
内存泄漏对应用的影响:
1.内存泄漏对于APP没有直接危害,及时有发现内存泄漏的情况,也不一定发生崩溃。
2.内存得不到释放,慢慢的会造成APP内存溢出,导致崩溃。
3.内存泄漏同时可能会出发系统频繁GC,发生内存抖动,会导致系统性能问题(不流畅)
下面转载于:https://mp.weixin.qq.com/s/Xk364e0PcINf3al8ViTuIg
安卓App 专项测试-内存泄露测试方法大概有6种,只要一看完就明白
1. 通过系统设置查看
在系统设置中->应用->正在运行->APP
优点:操作简单
缺点:数值不准确,无法实时查看数值变化
2. 通过命令行查看
adb shell dumpsys meminfo yourpakagename
其中Pss对应的TOTAL值为内存所实际占用的值
优点:简单方便,数据全面精确
缺点:无法实时查看内存占用
但这个可以通过批处理来进行实现:
代码如下:
set process=com.ssn.me5600@adb shell dumpsys meminfo %process% | findstr "Pss":m@adb shell dumpsys meminfo %process% | findstr "TOTAL"@ping -n 5 127.1>null@goto m3. 通过系统API查看
首先通过activitymanager获得正在运行的程序列表,找到所要获取的程序的pid。
activitymanager.getRunningAppProcesses()
再通过memoryinfo[0].getTotalPss();方法获得实际内存占用
Memoryinfo中还包括getTotalPrivateDirty和getTotalSharedDirty方法
优点:可拓展性高,可以通过程序实时查看内存的占用;数据全面精确
缺点:需要具有开发能力,入手较为困难,所以我们现在在测试内存的时候,是使用了内部自己研发的一款APP来监测内存的,这个APP目前可以实现实时监测并记录数据结果,可以提供给开发者和测试者分析内存的数据支持。目前仍然属于内测阶段,以后有机会可以提供给大家使用。
4. 通过SDK的ddms.bat(旧版本),新版本SDK名字叫monitor.bat
使用DDMS中的Heap:
1) 打开DDMS并打开Devices视图和Heap视图
2) 点击选择要监控的进程
3) 选中Devices视图界面上的”update heap” 图标
4) 点击Heap视图中的”Cause GC” 按钮(相当于进行了一次GC的操作)
一般我们会观察Data Object的Total值,正常情况下在每次GC后,这个值都会有明显的回落并会稳定在一个范围之内,说明代码中没有未被释放的内存;若这个值在每次GC后没有出现明显的回落,则说明代码中可能存在没有被释放的内存。
5. APP测试腾讯GT,Emmagee
6. 利用LeakCanary类然后插入到代码中,当有内存泄露的时候,跳出个提示;