内存泄漏造成的原因:
是生命周期长的对象持有生命周期短的对象的引用,造成生命周期短的对象使用完之后无法释放内存;
内存泄漏出现的场景
1.单例中的static成员间接或直接持有了activity的引用
2.非静态内部类持有父类的引用,如非静态handler持有activity的引用
3.异步操作如AsyncTask
4.资源对象没关闭造成的内存泄漏(如: Cursor、File等)
5.接收器、监听器注册没取消造成的内存泄漏,如广播,eventsbus
6.全局集合类强引用没清理造成的内存泄漏(特别是 static 修饰的集合)
如何避免内存泄漏
1.资源对象用完一定要关闭,最好加finally
2.一些接收器、监听器使用时候注册和取消成对出现
3.结合业务场景,设置软引用,弱引用,确保对象可以在合适的时机回收
4.使用LeakCannery自动化内存泄漏分析
OOM
据java的内存模型会出现内存溢出的内存有堆内存、方法区内存、虚拟机栈内存、native方法区内存.我们Android里面所说的大部分是指堆内存内存溢出,
内存溢出主的根本原因
1.app进程内存达到上限
1.1---申请内存的速度超出gc释放内存的速度
1.2---内存出现泄漏,gc无法回收泄漏的内存,导致可用内存越来越少
2.手机可用内存不足,这种情况并不是我们app消耗了很多内存,而是整个手机内存不足
对于申请内存的速度超出gc释放内存的速度的情况有以下几种
1.往内存中加载超大文件(特别是大图片)
2.循环创建大量对象(比如自定义View里面的onDraw方法里创建对象,会导致频繁GC,以致于内存抖动)
3.内存泄漏过多导致内存溢出,这个也是主要原因
一般解决方法
1.为应用申请更大内存,把manifest上的largdgeheap设置为true 这个方法不能治根
2.统一带有缓存的基础库,特别是图片库,如果用了两套不一样的图片加载库就会出现2个图片各自维护一套图片缓存
3.给ImageView设置合适尺寸的图片,列表页显示缩略图,查看大图显示原图
4.比如一些字符串拼接,最好是用StringBuilder(线程不安全)或者StringBuffer,如果直接String会导致频繁创建对象
5.优化业务架构设计,比如省市区数据分批加载,需要加载省就加载省,需要加载市就加载失去,避免一下子加载所有数据