内存泄漏&内存溢出
1.什么是oom,什么是内存泄漏以及原因
-
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现 out of memory;
-
内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。类似于内存上不可用的漏洞.
内存泄漏场景
- a)创建和应用生命周期一样的单例对象
不正确使用是引起内存泄露的一个常见问题,单例对象在被初始化后将在JVM的整个生命周期中存在(以静态变量的方式),如果单例对象持有外部对象的引用,那么这个外部对象将不能被jvm正常回收,导致内存泄露
b)创建匿名内部类的静态对象
c)未关闭资源
d)长时间存在的集合容器中创建生命周期短的对象
示例:A a = new A();
B b = new B(a);
a = null; //期望a被回收,但事实是b中还有a的引用,所以导致a内存地址不可用,导致泄漏。可以使用弱引用(当a失效时,所有的引用也失效)解决。
OOM几种常见的类型
栈溢出 比如循环的调用自己的方法,不断的在栈中压栈 堆溢出 可能在堆中创建了很多对象或者是储存了很大的数据,造成堆中放满了对象,再次有对象申请内存是,发现内存不足,就会报oom GC回收极限:回收时间过长,每次有98%的时间在回收内存,但只回收了不到2%的内存,多次GC后连续不到回收2%的情况下才会抛出异常,如果没有跑车,那就是GC回收的这点内存又会堆满,迫使GC又进行回收,造成恶性循环,使GC的使用率一直在100%工作,而没有任何效果
2.Thread是如何造成内存泄露的,如何解决?
比如说在主线程里创建了一个thread,里面run方法里在执行耗时的操作,当thread正在执行时,activity发生了横竖屏切换,那么原来的activity就应该先被销毁再进行重新创建,可是由于内部类持有外部类的引用,造成了thread在运行时还持有activity的引用,导致activity不能被回收,这时候就会发生内存泄漏,那么怎么解决呢,两种方法,一是设置为静态内部类,二是把持有的外部类引用改为弱引用,弱引用是当GC回收时,不管内存是否充足,只要发现弱引用的对象就进行回收
3.Handler导致的内存泄露的原因以及如何解决
因为handle时内部类,如果handle的looper和messagequeue在主线程,那么handle会持有外部类的引用,如果activity销毁时,handle还在运行,那么就会造成内存泄漏,解决它就是定义为静态的内部类,静态内部类不持有外部类的引用,其次是把持有的外部类引用改为弱引用,因为有可能需要访问外部类成员
4.如何加载Bitmap防止内存溢出
1对图片进行内存压缩;
2.高分辨率的图片放入对应文件夹;
3.内存复用
4.及时回收
5.MVP中如何处理Presenter层以防止内存泄漏的
activity是lifecycle的子类,也是通过lifecycle来释放资源 Lifecycle是Android中引入的主要用来观察和监听Activity、Fragment生命周期的一套观察者机制。 blog.csdn.net/huidevelope…