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

版权声明:本文为博主十月的原创文章,转载请注明出处! https://blog.csdn.net/liuxingrong666/article/details/86676809

内存优化对App来说至关重要,一般来说Android系统都会给一个App进程限制一定的内存空间,当内存使用超过这个限定大小的时候,就会发生内存溢出,造成手机卡顿、崩溃。内存使用不当的因素有很多,比如常见的内存泄露、内存抖动、Bitmap使用(使用第三方框架可以避免)等等。

一:内存泄露

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

1、LeakCanary

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

2、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占用的内存空间非常大,我们使用的过程要非常慎重,但是通过都会使用第三方框架来进行图片的管理,比如Gradle等等。

猜你喜欢

转载自blog.csdn.net/liuxingrong666/article/details/86676809