Android有关内存的知识点

引用类型

  1. 强引用(StrongReference): 只要被持有, 就不会被GC回收
  2. 软引用(SoftReference): 只有在内存空间不足时,才会被回收; 可以用来做内存缓存
  3. 弱引用(WeakReference): 不管内存是否足够,一旦GC发现弱引用对象,都会被回收
  4. 虚引用(PhantomReference): 任何时候都有可能被GC回收

常见内存泄漏

内存泄漏是指new出来的对象,无法被GC回收, 或者在对象在该被回收时,还被其他对象持有, 无法被回收;

一般来说, 主要是由持有Object的对象, 和Object的生命周期不一样导致; 持有Object的对象会比Object本身生命周期长, 从而导致Object无法被释放;
比如, 单例持有其他对象, 消息队列持有其他对象;

1. 单例持有不该持有的对象

单例生命周期和应用是一样长的, 持有其他对象造成无法释放;

2. 非静态的内部类和匿名内部类

非静态内部类和匿名内部类都会持有外部类的引用, 如果不注意, 容易造成外部类

3. Handler造成的内存泄漏

  1. 当Handler有延迟任务时, 消息队列会中的Message会持有对Handler的引用, 而Hander由持有对外部类的潜在引用;
    解决办法:
    1、可以把Handler类放在单独的类文件中,或者使用静态内部类便可以避免泄露;
    2、如果想在Handler内部去调用所在的Activity,那么可以在handler内部使用弱引用的方式去指向所在Activity.使用Static + WeakReference的方式来达到断开Handler与Activity之间存在引用关系的目的。
  2. HandlerThread造成内存泄漏; 由于Looper是一个死循环, HandlerThread任务执行完成之后, 不会自动销毁, 要手动调用quit方法结束

4. 监听器未反注册

一般我们会向系统服务注册监听器, 用于在部分情况下回调我们的方法, 此时系统就会持有我们的对象, 如果没有反注册, 造成被持有的对象无法释放

5. IO, Cursor, TypedArray等未关闭回收

内存抖动

内存抖动是指在段时间内创建了大量对象, 从而造成内存紧张, 频繁的触发GC;
eg. 在for循环中创建大量的临时对象; 在View.onDraw方法中创建对象

解决办法:

  1. 尽量减少在频繁调用的方法中创建大量临时对象
  2. 使用对象池; eg. 系统的MotionEvent, Message等都采用的是对象池; 系统V4包中也提供了工具类Pool供App快速实现对象池

你可能感兴趣的:(Android有关内存的知识点)