Android性能优化之内存篇

2019-02-28  本文已影响0人  MY1112

android的内存优化一般从以下几个方面考虑:


内存泄漏

内存泄漏的本质:不合理的引用导致引用者对象的生命周期>被引用者对象的生命周期。当回收被引用者对象时发现该对象还在被引用状态,无法被回收,就出现了内存泄漏。

常见的内存泄漏场景:

比如经典的在一个Activity里new一个非static 的Handler对象、在Activity里new了一个非静态的Thread或者Runnable。还有很多类似的,尤其是在Activity或者Fragment内引用一个非静态的匿名内部类时,这个类都会持有外部类,相当于持有了context,极易导致context无法被回收,然后就内存泄漏。

解决方法:我们可以把这个内部类设置为静态的;或者不要使用内部类,在外面写个类;如果涉及到Context的必须持有问题,用Application的Context,因为其生命周期较长且唯一,可以不用回收,这样就不会泄漏。

我们知道,jvm层面static修饰的变量是放在方法区的,方法区是永久代,基本上不会发送GC,或者说其发送GC的条件非常苛刻,而且在java1.8后出现了元空间,回收更是遥遥无期,也就是说static修饰的变量的生命周期跟你的APP应用生命周期一样,如果你的static修饰的成员变量是Context或者持有Context时,那就会导致这个变量回收不掉,会莫名其妙用了很多内存,我们每次启动一个Activity都会new一个Context对象,如此反复你的内存很快就爆掉了。

解决方法:我们在写程序时不要用static修饰类似占用大资源的对象(例如Context,View)。

这个跟上面的static原理是一样的,因为单例模式是static的,其生命周期很长,所以要特别小心其持有对象导致内存泄漏。例如:常见的观察者模式+单例模式时,我们会在Activity里实现某个接口(观察者接口),然后把这个接口add到单例模式的ArrayList(被观察者),这个过程就相当于单例对象持有了一个Activity对象,如果在Activity destroy时没有把这个Activity从ArrayList里remove掉,那就造成内存泄漏了。

解决办法:单例模式里持有变量时要注意其生命周期的管理,有+也有-,这样才安全。另外在这种情况里,我们可以适当合理地使用WeakReference。

当一个集合使用完后没有清空其持有的对象。例如:我们往ArrayList里add一个对象时,有的时候我们把是把一个对象add进去,但是ArrayList真正持有的是这个对象的引用,所以即使我们把add的这个对象置null,但是还会依然持有对象的引用,也就等于还持有另外对象。

解决办法:当集合不用时,要清空然后置null。例如:arrayList.clear();arrayList=null;

例如:registerBroadcast最后没有unregisterBroadcast;数据库操作的cursor没有close;stream流未关闭;Bitmap没有recycle等;

解决办法:关闭或者释放相关的信息

例如:在ListView里没有复用好View而是创建了大量的View;Webview使用没有关闭;

内存泄漏分析、跟踪、监测的工具:

  1. Android Studio的Memory;
  2. MAT(Memory Analysis Tools);
  3. Heap Viewer;
  4. Allocation Tracker;
  5. LeakCanary;

至于如何利用这些工具进行内存的分析,后续我会慢慢补上。
以上都是理论知识,也是普遍的问题存在,而且相对来说比较容易理解,大部分开发人员也熟知,真正的提升需要在实践中,所以有时间大家可以参考外面文章的同时自己多实践。


内存抖动

所谓的内存抖动就是短时间里,内存出现了反复的波动,其出现的原因主要是因为短时间内,我们写代码时创建了大量的对象,频繁地触发了GC机制回收对象,如果回收的速度赶不上你创建的速度,极有可能就OOM了,而且创建了大量的对象再回收会导致磁盘空间占用比较分散,不利于整体分配内存,会影响内存利用率和使用效率等。避免内存抖动注意以下几种:

其实内存抖动还是比较容易定位的,这一块的分析和修改也没有太大的难度,就不做过多的分析了。


Bitmap的使用

在很多的项目中,Bitmap占用的内存达到了整个App占用内存的50%,甚至更高。Bitmap的优化一般从如下几个方面考虑:

关于Bitmap推荐一篇文章https://mp.weixin.qq.com/s?__biz=MzA3NTYzODYzMg==&mid=403263974&idx=1&sn=b0315addbc47f3c38e65d9c633a12cd6&scene=21#wechat_redirect


代码质量

就是写代码过程里要注意一些小细节。

上一篇 下一篇

猜你喜欢

热点阅读