App内存使用对比分析

 最近尝试对app内存使用情况进行检测对比,由于是刚刚接触这方面的知识,在很多方面都是处于一个认知的阶段,下面通过以下例子来进行分析对比:

一、(1)一个页面正常的情况下内存的使用情况:

从上图可以看出,这个页面的内存使用是比较平缓的,只是在加载数据或者进行点击事件的时候就会产生一些波动,当点击事件结束或者退出这个页面的时候就会出现一些灰色的区域,代表着这部分的内存已经被回收掉了。接下来通过memory analyzer生成内存使用饼状图,

从上面的图我们只是能看到内存在各个方面使用的大概比例,为了能够直观的体现出来区别,我让其与一个存在内存溢出的例子进行对比。

(2) 内存溢出的情况:

在原来的代码加上以下代码:


在这之后,重复进行“进入—退出”这个界面的操作,我们会发现内存使用会发生很大的变化。



内存使用成倍增长,而且出现了很多凹凸不平的峰值,通过MAT查询语句查询的结果如下:



当我退出这个界面,内存还存在着很多个社区话题详情(CommunityDetailActivity)页面,这明显出现了不正常,退出了这个Activity会回收掉这个页面所消耗的内存,这里非但没有回收掉,反而一直上升,通过上面的方法我们可以定位到CommunityTopicListAdapter中的Thread中,经过查找可以发现CommunityDetailActivity被内部类引用,而内部类又被线程引用,因此退出该页面的时候无法释放,GC无法回收造成内存泄漏。

解决方法:在使用线程的时候控制好睡眠的时间。

二、在很多时候我们通常会用到ListView进行开发,我们会发现在使用适配器的时候通常会进行控件复用来减少对内存的消耗,事实上不知道用跟没有用的区别区别在哪里,所以我通过下面的例子进行对比分析:


使用控件复用的情况(图一)



没有使用控件复用的情况(图二)

使用控件复用时内存消耗较大的几项



没有使用控件复用时内存消耗较大的几项

从图中我们可以看到ListView持有了大量的对象引用,其中TextView数量达到1000多,而在正常情况下,ListView会复用类型相同的view,其中的对象个数不可能如此庞大,因此,从这里就可以断定ListView使用不当出现了内存泄漏。


三、WebView加载html



从上图可以看到,Webview如果加载的页面有很多图片就会发现内存占用会上升,当退出这个页面的重新进来,JVM就会把一些内存释放掉,让webview在加载html时处于一个“上升—下降”的状态,不过通过图片可以看到,在不断加载和浏览多个html后内存会有所上升,因为它在不断加载的过程中会产生一些缓存数据。

解决方法:在退出该webview页面的时候把webview的缓存历史清除掉,webview.clearHistory();

webview.clearCache(true);

webview.freeMemory();

webview = null;


四、我们在使用MAT分析这些页面的时候会发现,大多数情况下MAT会把"android.graphics.Bitmap"作为内存泄漏的怀疑对象,结果如图所示:


dominator_tree页面我们可以看出来因为"android.graphics.Bitmap"Retained Head是比较大的,在分析内存泄漏时,内存最大的是需要去怀疑是否存在着泄漏。


所以下面就对"android.graphics.Bitmap"进行分析,经过Path To GC Roots-> exclude weak references过滤掉弱引用可以得到下图:


从上图可以看出来最后的子文件的文件图标下面有一个黄色的小点,这代表着能够被GC Roots访问到,这就代表着不能被回收掉,这就解决了为什么Mat一直把"android.graphics.Bitmap"作为怀疑的对象。

猜你喜欢

转载自blog.csdn.net/kaoshibiguo_1/article/details/53894230
今日推荐