Android性能优化(二) 内存优化

Android系统一般会限制一个App进程的内存使用大小,当内存使用超过这个大小的时候,就会发生内存溢出,造成App卡顿、崩溃。内存使用不当的因素有很多,比如常见的内存泄露、内存抖动、Bitmap的使用问题(使用第三方框架可以避免)等等

一:内存泄露

在Android系统中,虚拟机有垃圾自动回收机制,不定期地对无用的对象进行回收清理,回收一个对象的主要依据是当前对象有没有被强引用,如果一个本该被回收的对象,但是因为某种原因被强引用了,就造成这个对象无法被回收,这就是内存泄露。如果这种对象越积越多,会造成手机卡顿,最后就是内存溢出直接崩溃

1、LeakCanary

LeakCanary是一个检测内存泄露的第三方框架,集成到项目中,使用起来非常简单,只要检测到App有内存泄露发生,就会有吐司提示,并且从界面中可以清楚地看到泄露对象的引用路径,如下图:

2、Memory Monitor

Memory Monitor是Android Studio自带的内存检测工具,通过Memory Monitor可以方便地观察到App的内存使用情况,看看它的界面

上面是内存检测的一个界面截图,其中红色箭头标识的1、2、3分别代表:

1.手动触发GC进行内存回收

2.Dump Java Heap获取当前的堆栈信息,生成一个.hprof文件,通过这个文件可以看到VM在当前时刻包含的类的实例和数组对象,通常可以进行内存泄露的分析

3.追踪内存使用情况,第一次点击此按钮代表开始追踪,一段时间后再点击代表结束追踪,可以记录在这段时间区间内各个线程中各个方法的内存分配情况,一般用于追踪某项操作之后的内存分配,调整相关的方法调用来优化app性能与内存使用

2.1、用Dump Java Heap分析内存泄露

用Dump Java Heap生成的hprof文件,可以看到VM堆栈里面的对象分配情况,可以通过这种方法检测追踪到发生内存泄露的地方,通常操作步骤如下:

  • 以App的主界面为起点,手动操作打开App的各个界面,尽量对整个App的功能都做一遍操作
  • 然后回到App主界面,点击按钮手动触发GC回收内存
  • 最后通过Dump Java Heap获取当前堆栈信息,从生成的.hprof文件中,我们就可以看到有哪些对象没有被回收,从而定位内存泄露的对象

下面通过实例来演示分析内存泄露的步骤,经过上面所说的一顿操作,最后生成了一个.hprof文件如下

其中:

Alloc Count:生成对象的数量

Shallow Size:这些对象所占用的内存(不包括引用对象)

Retained Size:这些对象所占用内存(包括应用对象),内存释放时,实际释放的大小就是这里的大小

下一步就进去我们App的包结构中看看有哪些对象没有被释放,这里是指com那个包

 

MainActivity是我们的主界面,突然发现一个MemoryActivity没有被回收,按理来说这个对象是要被回收的,所以首先怀疑这个activity发生了泄露

现在定位到了MemoryActivity对象发生了泄露,但还不知道它被谁强引用了,为了更好地分析出内存泄露发生的原因,我们就要用到MAT(Memory Analyzer Tool)这个工具来分析hprof文件了

2.2 MAT工具分析内存泄露

【没有这个工具的小伙伴可以戳这里–>Eclipse Memory Analyzer Open Source Project

用Dump Java Heap生成的hprof文件是不能用MAT打开的,所以先转化一下,首先在Android Studio中将hprof文件导出到电脑上,点击下面按钮

然后通过cmd命令:hprof-conv [原文件全路径名] [转换后文件全路径名],做一个转换操作,再使用MAT工具打开

MAT的功能其实蛮多的,这里就不一一介绍了,主要讲解如何查找内存泄露原因,点击左下角的Histogram,显示如下

因为我们已经知道哪个对象发生内存泄露了,直接搜索MemoryActivity找到此对象,右键打开如下

选择“merge shortest Path to GC Roots” -> “exclude all phantom/weak/soft etc. references”,把虚引用,弱引用,软引用全部进行过滤掉,只查看对当前对象的强引用,结果如下:

发现是EventBus的强引用,回去MemoryActivity查看代码, 原来是因为EventBus没有在onDestroy方法中进行注销,所以泄露了

 

二:内存抖动

内存抖动是指大量对象在短时间被创建又在短时间内被回收释放,瞬间产生大量的对象会严重占用虚拟机新生代的内存区域,当达到阈值时就会触发GC,如果GC被频繁触发,势必影响到UI界面的流畅性能

常见发生内存抖动的地方, 比如在for循环中被频繁创建某个对象,或者其他循环中,这个问题我们平时编程的过程要多加注意,也可以通过android studio内存检测工具查看内存的变化趋势

三:Bitmap的使用

Bitmap占用的内存空间非常大,使用的过程要非常慎重,一般我们都会通过使用第三方框架来进行图片的加载管理,图片通过设置三级缓存来管理和保存,其中用到内存缓存的LRUCache技术和硬盘缓存的DiskLruCache技术,这里就不展开讨论了,常见的框架有Glide、Picasso等等

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值