内存泄漏与内存溢出的区别
内存溢出:程序在申请内存时,没有足够的内存空间供其使用,出现out ofmemory
Android系统为每个应用程序申请到的内存有限,一般为64M或者128M,可以在清单文件中进行配制,android:largeheap
堆内存溢出代表:生产者与消费者模型,注册回调,忘记注销,忘记控制队列大小
栈内存溢出代表:方法的递归
内存泄漏:程序在申请内存后,被某个对象一直持有,无法释放已经申请的内存空间
一次内存泄漏可以忽略,但内存泄漏堆积后果很严重,无论多少内存,迟早会被占光
(总结一句话就是对象的生命存活时间不一致导致)
内存泄漏情况一:单例模式
错误情况:context生命周期过长
正确方式
内存泄漏情况二:静态变量导致内存泄漏。静态变量存储在方法区,他的生命周期从类加载开始,到整个进程结束。一旦静态变量初始化后,他所持有的引用只有等到进程结束才会释放。
错误情况:静态变量导致内存泄漏
正确修改方式:在生命周期onDestroy时静态变量赋值空
内存泄漏情况三:非静态内部类导致内存泄漏。非静态内部类(包括匿名内部类)默认就会持有外部类的引用,当非静态内部类对象的生命周期比外部类对象的生命周期长时,就会导致内存泄漏。常见(Handler,Thread,AsyncTask)
错误情况:handler生命周期比Activity生命周期长,(Handler)会被底层的ThreadLoad绑定,再调用外部对象或方法时可能会出现空指针异常,Activity也不能被回收
正确修改方式:将外部类使用弱指针引用
内存泄漏情况四:未取消注册或回调导致内存泄漏。比如在Activity中注册广播,如果在Activity销毁后不取消注册,那么这个广播会一直存在系统中,同上面所说的非静态内部类一样持有Activity引用,导致内存泄漏。因此注册广播后再Activity销毁后一定要取消注册。
内存泄漏情况五:集合中的对象未清理造成内存泄漏。在循环中把引用o释放了,但是它被添加到了objectList中,所以objectList也持有对象的引用,此时该对象时无法被GC的。因此对象如果添加到集合中,还必须从中删除,最简单的方法防止集合类泄漏内存的方法。
内存泄漏情况六:资源未关闭或释放导致内存泄漏。在使用流或者等资源时要及时关闭。这些资源在进行读写操作时通常都使用了缓冲,如果不及时关闭,这些缓冲对象就会一直被占用而得不到释放,以致发生内存泄漏。因此我们在不需要使用他们的时候就及时关闭,以便缓冲能及时得到释放,从而避免内存泄漏。
Webview持有activity的引用,造成Webview内存无法释放,即使是调用了Webview.destory()等方法都无法解决问题
最终的解决方案是:在销毁Webview之前需要先将Webview从父容器中移除,然后再销毁Webview
内存溢出
内存溢出分为堆内存溢出和栈内存溢出
内存溢出出现的点:堆内存,虚拟机栈
内存泄漏出现的点:方法区,堆内存,虚拟机栈