关闭

android 内存性能优化

标签: android内存性能优化内存泄露
239人阅读 评论(0) 收藏 举报
分类:
android 内存优化和性能优化问题

一.内存优化

Android应用开发中常出现的一种内存问题就是内存泄露OOM,内存泄漏的能导致问题就是

1:应用卡顿,响应速度慢(内存占用高时JVM虚拟机会频繁触发GC);

2.应用莫名的崩溃(上面应用内存原理有介绍,也就是超过了阈值OOM);

1.内存泄漏的常见情况分析


    1.1.Context使用不当造成内存泄露;不要对一个Activity Context保持长生命周期的引用(譬如上面概念部分给出的示例)。尽量在一切可以使用应用 ApplicationContext代替Context的地方进行替换(原理我前面有一篇关于Context的文章有解释)。
    
    1.2.非静态内部类的静态实例容易造成内存泄漏;即一个类中如果你不能够控制它其中内部类的生命周期(譬如Activity中的一些特殊Handler等),则尽量使用静态类和弱引用来处理(譬如ViewRoot的实现)。

    1.3.警惕线程未终止造成的内存泄露;譬如在Activity中关联了一个生命周期超过Activity的Thread,在退出Activity时切记结束线程。一个典型的例子就是HandlerThread的run方法是一个死循环,它不会自己结束,线程的生命周期超过了Activity生命周期,我们必须手动在Activity的销毁方法中中调运thread.getLooper().quit();才不会泄露。

    1.4.对象的注册与反注册没有成对出现造成的内存泄露;譬如注册广播接收器、注册观察者(典型的譬如数据库的监听)等。

    1.5.创建与关闭没有成对出现造成的泄露;譬如Cursor资源必须手动关闭,WebView必须手动销毁,流等对象必须手动关闭等。

    1.6.不要在执行频率很高的方法或者循环中创建对象,可以使用HashTable等创建一组对象容器从容器中取那些对象,而不用每次new与释放。

    1.7.避免代码设计模式的错误造成内存泄露;譬如循环引用,A持有B,B持有C,C持有A,这样的设计谁都得不到释放。

2.内存泄漏的检测工具

    2.1.AS的Memory窗口
    2.2.DDMS-Heap内存监测工具
    2.3.leakcanary (参考Android stduio 常用插件那篇博客有介绍使用)

3.Android 规避内存溢出OOM建议

    3.1.时刻记得不要加载过大的Bitmap对象;譬如对于类似图片加载我们要通过BitmapFactory.Options设置图片的一些采样比率和复用等,具体做法点我参考官方文档,不过过我们一般都用fresco或Glide开源库进行加载。

    3.2.优化界面交互过程中频繁的内存使用;譬如在列表等操作中只加载可见区域的Bitmap、滑动时不加载、停止滑动后再开始加载。

    3.3.有些地方避免使用强引用,替换为弱引用等操作。

    3.4.避免各种内存泄露的存在导致OOM。

    3.5.对批量加载等操作进行缓存设计,譬如列表图片显示,Adapter的convertView缓存等。

    3.6.尽可能的复用资源;譬如系统本身有很多字符串、颜色、图片、动画、样式以及简单布局等资源可供我们直接使用,我们自己也要尽量复用style等资源达到节约内存。

    3.7.对于有缓存等存在的应用尽量实现onLowMemory()和onTrimMemory()方法。

    3.8.尽量使用线程池替代多线程操作,这样可以节约内存及CPU占用率。

    3.9.尽量管理好自己的Service、Thread等后台的生命周期,不要浪费内存占用。

    3.10.尽可能的不要使用依赖注入,中看不中用。

    3.11.尽量在做一些大内存分配等可疑内存操作时进行try catch操作,避免不必要的应用闪退。

4.垃圾回收机制

  先来说说内存优化中的GC (垃圾回收机制),垃圾收集算法的核心思想是:对虚拟机可用内存空间,即堆空间中的对象进行识别,如果对象正在被引用,那么称其为存活对象,反之,如果对象不再被引用,则为垃圾对象,可以回收其占据的空间,用于再分配。对于GC来说,对象的不同引用强度对于何时回收是不同的。gc其实是在一个优先级较低的线程中执行的,虚拟机在执行GC垃圾回收操作时所有线程(包括UI线程)都需要暂停,当GC垃圾回收完成之后所有线程才能够继续执行,大量GC操作可能会导致界面卡顿的问题。
   4.1 强引用 StrongReference
     一般我们常用到的引用就是强引用,常见形式如:A a = new A();等。强引用本身存储在栈内存中,其存储指向对内存中对象的地址。一般情况下,
     当对内存中的对象不再有任何强引用指向它时,垃圾回收机器开始考虑可能要对此内存进行的垃圾回收。如当进行编码:a = null,此时,刚刚在堆中分配地址并新建的a对象没有其他的任何引用,当系统进行垃圾回收时,堆内存将被垃圾回收。
   4.2 软引用 SoftReference
     对于GC来说, SoftReference的强度明显低于 SrongReference。 SoftReference修饰的引用,其告诉GC:我是一个 软引用,当内存不足的时候,
     我指向的这个内存是可以给你释放掉的,来看一下android系统中的一个使用实列
     private SoftReference<Bitmap> mBitmapCache = new SoftReference<Bitmap>(null);
  public Bitmap getIpMessageBitmap() {
    return mBitmapCache.get();
  }
  public void setIpMessageBitmapCache(Bitmap bitmap) {
    if (null != bitmap) {
      mBitmapCache = new SoftReference<Bitmap>(bitmap);
    }
  }
   4.3 弱引用WeakReference:
      对于GC来说, WeakReference 的强度又明显低于 SoftReference 。 WeakReference 修饰的引用,其告诉GC:我是一个弱 引用,对于你的要求我没有话说, 我指向的这个内存是可以给你释放掉的。我们来看一下android系统中的一个使用实列(InstalledAppDetails.java 这是一段停用一个APP的代码段,其中这个 需要停用APP的InstalledAppDetails对象 在这里的引用就采用了弱引用
  static class DisableChanger extends AsyncTask<Object, Object, Object> {
  final PackageManager mPm;
  final WeakReference<InstalledAppDetails> mActivity;
  final ApplicationInfo mInfo;
  final int mState;

  DisableChanger(InstalledAppDetails activity, ApplicationInfo info, int state) {
      mPm = activity.mPm;
      mActivity = new WeakReference<InstalledAppDetails>(activity);
      mInfo = info;
      mState = state;
  }
    }
    4.4 虚引用 PhantomReference:
    PhantomReference并不会改变其指示对象的垃圾回收时机,ReferenceQueue的作用主要是用于监听SoftReference/WeakReference/PhantomReference的指示对象是否已经被垃圾回收。


二.应用UI性能问题

1 应用UI卡顿常见原因    

    1.1.人为在UI线程中做耗时操作,导致UI线程卡顿;
    1.2.布局Layout过于复杂,无法在一定时间内完成渲染;   
    1.3.View过度绘制或动画效果的过度使用,从而使CPU或GPU负载过重;
    1.4.View频繁的触发measure、layout,导致measure、layout累计耗时过多及整个View频繁的重新渲染;
    1.5.内存频繁触发GC过多(同一帧中频繁创建内存),导致暂时阻塞渲染操作;   
    1.6.ANR;(1.在5秒内没有响应输入的事件(例如,按键按下,屏幕触摸)
     2.BroadcastReceiver在10秒内没有执行完毕:造成以上两点的原因有很多主线程中做了非常耗时的操作,比如说是下载,io异常)

2.应用UI性能分析解决


    2.1.布局优化;尽量使用include、merge、ViewStub标签,尽量不存在冗余嵌套及过于复杂布局(譬如10层就会直接异常),尽量使用GONE替换INVISIBLE,使用weight后尽量将width和heigh设置为0dp减少运算,Item存在非常复杂的嵌套时考虑使用自定义Item View来取代,减少measure与layout次数等。
    2.2.列表及Adapter优化;尽量复用getView方法中的相关View,不重复获取实例导致卡顿,列表尽量在滑动过程中不进行UI元素刷新等。
    2.3.背景和图片等内存分配优化;尽量减少不必要的背景设置,图片尽量压缩处理显示,尽量避免频繁内存抖动等问题出现。
    2.4.自定义View等绘图与布局优化;尽量避免在draw、measure、layout中做过于耗时及耗内存操作,尤其是draw方法中,尽量减少draw、measure、layout等执行次数。

    2.5.避免ANR,不要在UI线程中做耗时操作,遵守ANR规避守则,譬如多次数据库操作等。


参考博客:

1.http://blog.csdn.net/u010687392/article/details/50721437  内存优化

http://blog.csdn.net/u010687392/article/details/47809295    hashmap 的替代

0
0
查看评论

Android 性能优化之内存优化

Android 性能优化之内存优化 Android 应用程序在开发的过程中内存的准确控制是判断一个程序好坏的重要标准之一: 一、假如我们开发的程序内存溢出、泄漏了会引发那些实质性的问题呢?    1、程序卡顿、响应速度变慢。    2、开启其他程序的时候,内存...
  • xgangzai
  • xgangzai
  • 2016-12-18 20:33
  • 15005

Google官方 详解 Android 性能优化【史诗巨著之内存篇】

尊重博主原创,如需转载,请附上本文链接http://blog.csdn.net/chivalrousman/article/details/51553114#t16 为什么关注性能对于一款APP,用户首先关注的是 app的性能,而不是APP本身的属性功能,用户不关心你是否是搞社交,是否搞电商,是否是...
  • chivalrousman
  • chivalrousman
  • 2016-06-01 18:19
  • 11014

Android性能优化系列之内存优化

在Java中,内存的分配是由程序完成的,而内存的释放是由垃圾收集器(Garbage Collection,GC)完成的,程序员不需要通过调用函数来释放内存,但也随之带来了内存泄漏的可能,上篇博客,我介绍了 Android性能优化系列之布局优化,本篇博客,我将介绍内存优化的相关知识。内存的分配策略概述...
  • u012124438
  • u012124438
  • 2017-01-21 21:00
  • 6804

Android之——性能与内存优化

写出高效代码的两条基本的原则:(1)不要做不必要的事;(2)不要分配不必要的内存。 1. 内存优化       Android系统对每个软件所能使用的RAM空间进行了限制(如:Nexus one 对每个软件的内存限制是24M),同时Java语言本身比较消耗内...
  • l1028386804
  • l1028386804
  • 2015-07-21 17:29
  • 3164

Android性能优化(App整体优化)

整理一系列的专题,比如APK瘦身、插件化、程序架构、性能优化、自定义view、增量升级、移动开发各种技术解决方案等。 Android后期发展的五大趋势:一、性能优化;二、高级UI;三、JNI/NDK开发;四、架构师;五、RN开发; 性能优化有那几个方面:一、内存优化;二、UI优化(布局优化和...
  • ShareUs
  • ShareUs
  • 2016-08-14 16:51
  • 979

Android开发性能优化总结(一)

安卓开发应用首先要讲究良好的用户体验,如果一款软件卡顿现象严重,不流畅,经常崩溃,那么将给用户带来极不良好的体验,从而损失用户。 在实际开发和学习中,我总结了一下关于安卓性能的优化,供大家参考交流。应用程序的性能问题体现在很多方面, 比如第一次启动速度慢,或者进入某一界面速度慢;动画执行过程不流畅...
  • gs12software
  • gs12software
  • 2016-04-17 16:04
  • 20519

[Android 性能优化系列]内存之基础篇--Android如何管理内存

[Android 性能优化系列]内存之基础篇--Android如何管理内存
  • kifile
  • kifile
  • 2014-11-02 22:23
  • 2267

Android性能优化之电量优化

1、在android framework里面有专门负责电量统计的Service:BatteryStatsSerive ①这个Service在ActivityManagerService中创建,代码如下: mBatteryStatsService = new BatteryStatsSer...
  • zhaodecang
  • zhaodecang
  • 2016-11-26 00:40
  • 16263

android app性能优化大汇总(内存性能优化)

android app性能优化大汇总(内存性能优化) 转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持!   写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上把网...
  • zhaoweixing1989
  • zhaoweixing1989
  • 2016-10-21 16:27
  • 850

Android性能优化系列---管理你的app内存(一)

Random-access memory(RAM)在任何软件开发环境都是稀有资源,在移动操作系统物理内存有限的情况下将显得更加珍贵.虽然Android的Dalvik虚拟机优化了内存回收机制,但我们也要关注你的app的内存分配和释放。 为了垃圾回收器能回收你系统的内存,你应该避免引起...
  • xhmj12
  • xhmj12
  • 2016-02-03 13:06
  • 404
    个人资料
    • 访问:7979次
    • 积分:330
    • 等级:
    • 排名:千里之外
    • 原创:25篇
    • 转载:4篇
    • 译文:0篇
    • 评论:2条
    最新评论