欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android性能优化和常见内存泄漏、内存溢出

程序员文章站 2022-07-02 12:13:10
...

Android性能优化

  • 不要在UI线程中做耗时操作,避免ANR
  • 合理使用StringBuffer、StringBuilder、String
  • I/O流用完及时关闭,WebView用完手动销毁
  • 使用IntentService代替Service
  • 采用merge优化布局层数。 采用include来共享布局
  • 避免使用枚举
  • 合理使用布局控件,重视界面的布局优化
  • 避免创建不必要的对象,集合中的对象要及时清理
  • 使用Application Context代替Activity中的Context
  • 将png、jpg格式的图片转换为webp格式图片

  • 使用线程池代替多线程操作,避免创建、销毁线程带来的内存开销

  • 加载较大Bitmap时先压缩再使用,加载高清大图时使用
  • BitmapRegionDecoder分段加载(可见才加载),不使用的Bitmap及时recycle()
  • 采用延迟加载数据、数据缓存等手段提高性能
  • 采用延时加载View,采用ViewStub避免一些不经常使用的视图长期被引用,占用内存

  • 采用合理的数据结构和算法提高程序性能

  • 优先使用增强for循环,效率更高,但对ArrayList进行遍历时,使用普通的for循环效率要更高,因为ArrayList实现RandomAccess接口。
    (RandomAccess是标记接口,用于标记当前类是可以随机访问的,当一个类标记了RandomAccess接口,那么表明该类使用for循环遍历效率更高,如果没用RandomAccess标记,则使用迭代器遍历效率更高)
  • 在Android设备中,浮点数会比整型慢两倍,所以避免使用浮点数,一些处理器有硬件乘法但是没有除法,而除法是用软件实现的,所以尽量使用乘法,以便提高效率
  • 因Android的内存有限,在有限范围内(如包内访问)访问Bean中的字段,尽量把字段声明为public直接访问,避免使用Getters/Setters,直接访问的速度比间接访问要快7倍
  • ViewPager同时缓存page数最好为3,如果过多,pager累积渲染耗时就会增多,可能会卡
  • 采用合理的数据结构和算法提高程序性能,这往往是决定程序性能的关键,
    使用实体类比接口好
    假设你有一个HashMap对象,你可以将它声明为HashMap或者Map
Map map1 = new HashMap();
HashMap map2 = new HashMap();
哪个更好呢?

按照传统的观点Map会更好些,因为这样你可以改变他的具体实现类,只要这个类继承自Map接口。
传统的观点对于传统的程序是正确的,但是它并不适合嵌入式系统。
调用一个接口的引用会比调用实体类的引用多花费一倍的时间。
如果HashMap完全适合你的程序,那么使用Map就没有什么价值。如果有些地方你不能确定,
先避免使用Map,剩下的交给IDE提供的重构功能好了。(当然公共API是一个例外:一个好的API常常会牺牲一些性能)

Android中常见的内存泄漏

  • Context使用不当造成内存泄露,如单列对象持有Activity
  • 非静态内部类创建静态实例造成的内存泄漏,因内部类创建的对象被Static修饰
  • Handler造成的内存泄漏,因非静态内部类持有外部类引用
  • 线程未终止造成的内存泄漏,如子线程未执行完只有外部类引用
  • 对象的注册与反注册没有成对出现造成的内存泄露,如广播
  • 创建与关闭没有成对出现造成的泄露,如Cursor资源,流,WebView需要手动销毁
  • 不要在执行频率很高的方法或者循环中创建对象
  • 避免代码设计模式的错误造成内存泄露,如单列对象持有Activity
  • 尽量避免使用 static 修饰成员变量
  • 一些不良代码造成的内存压力

Android中常见的内存溢出

  • 内存泄漏最终都会内存溢出
  • 加载图片过大
  • Static引用对象,使对象内存过大
  • 资源使用完未及时释放,长期保持某些资源
  • 多线程导致内存溢出
  • 在递归和循环中创建大量对象