Android内存泄露的总结

来源:互联网 发布:淘宝充值送优酷会员 编辑:程序博客网 时间:2024/06/10 03:30

Android内存优化主要包括两方面的工作:
优化RAM,即降低运行时内存。这里的目的是防止程序发生OOM异常,以及降低程序由于内存过大被LMK机制杀死的概率。另一方面,不合理的内存使用会使GC大大增多,从而导致程序变卡。
优化ROM,即降低程序占ROM的体积。这里主要是为了降低程序占用的空间,防止由于ROM空间不足导致程序无法安装。

平时注意
1, 只要开发者平时注意,养成良好的编码习惯,比较容易发现的内存泄漏的地方
1. 注册监听器的泄漏
2. Cursor,Stream没有close,View没有recyle
3. 集合中对象没清理造成的内存泄漏
2,安卓开发需要注意的是:

1.单例造成的内存泄露
原因:构造Adapter时,没有使用缓存的ConvertView
解决方法:使用弱引用

2.InnerClass匿名内部类
解决方法:
将内部类变成静态内部类;

3 Activity Context 的不正确使用

   这在安卓开发中容易的问题,产生问题的原因:在Android应用程序中通常可以使用两种Context对象:Activity和Application。当类或方法需要Context对象的时候常见的做法是使用第一个作为Context参数。这样就意味着View对象对整个Activity保持引用,因此也就保持对Activty的所有的引用。

解决的方案:使用使用ApplicationContext代替ActivityContext

4, Handler引起的内存泄漏
原因:当Handler中有延迟的的任务或是等待执行的任务队列过长,由于消息持有对Handler的引用,而Handler又持有对其外部类的潜在引用,这条引用关系会一直保持到消息得到处理,而导致了Activity无法被垃圾回收器回收,而导致了内存泄露。

解决方案使用:可以把Handler类放在单独的类文件中,或者使用静态内部类便可以避免泄露;
如果想在Handler内部去调用所在的Activity,那么可以在handler内部使用弱引用的方式去指向所在Activity.使用Static + WeakReference的方式来达到断开Handler与Activity之间存在引用关系的目的。

5 WebView造成的泄露
不再使用WebView对象时,应该调用它的destory()函数来销毁它,并释放其占用的内存,否则其占用的内存长期也不能被回收,从而造成内存泄露。

推荐使用的一种方案:
为webView开启另外一个进程,通过AIDL与主线程进行通信,WebView所在的进程可以根据业务的需要选择合适的时机进行销毁,从而达到内存的完整释放。

内存泄露的监控方案

Square的开源库leakcanry是一个非常不错的选择,它通过弱引用方式侦查Activity或对象的生命周期,若发现内存泄露自动dump Hprof文件,通过HAHA库得到泄露的最短路径,最后通过notification展示。

内存泄露判断与处理的流程如下图 ,各自运行的进程空间(主进程通过idlehandler,HAHA分析使用的是单独的进程):

这里写图片描述

减低运行内存时的一些方法

1,降低运行时内存的一些方法

2, 自身内存占用监控
对于系统函数onLowMemory等函数是针对整个系统而已的,对于本进程来说,其dalvik内存距离OOM的差值并没有体现,也没有回调函数供我们及时释放内存。假若能有那么一套机制,可以实时监控进程的堆内存使用率,达到设定值即关于通知相关模块进行内存释放,这会大大的降低OOM。

实现原理
这个其实比较简单,通过Runtime获得maxMemory,而totalMemory-freeMemory即为当前真正使用的dalvik内存。

Runtime.getRuntime().maxMemory();
Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
操作方式
我们可以定期(前台每隔3分钟)去得到这个值,当我们这个值达到危险值时(例如80%),我们应当主要去释放我们的各种cache资源(bitmap的cache为大头),同时显示的去Trim应用的memory,加速内存收集。

WindowManagerGlobal.getInstance().startTrimMemory(TRIM_MEMORY_COMPLETE);
3,使用多进程
4. 上报OOM详细信息

当系统发生OOM的crash时,我们应当上传更加详细的内存相关信息,方便我们定位当时内存的具体情况。

其他例如使用large heap、inBitmap、SparseArray、Protobuf等不再一一细述,对代码采用优化–埋坑–优化–埋坑的方式并不推荐。我们应该着力于建立一套合理的框架与监控体系,能及时的发现诸如bitmap过大、像素浪费、内存占用过大、应用OOM等问题。

参考的文章

优化安卓应用内存的神秘方法以及背后的原理,一般人我不告诉他

Android性能优化之内存篇

原创粉丝点击