Android中常见内存泄露以及优化方案
一.Android内存泄露一般定义
如果一个无用对象(不需要再使用的对象)仍然被其他对象持有引用,造成该对象无法被系统回收,以致该对象在堆中所占用的内存单元无法被释放而造成内存空间浪费,这中情况就是内存泄露
二.常见的内存泄漏以及优化方案
(1)单例导致内存泄露:单例模式在 Android 开发中会经常用到,但是如果使用不当就会导致内存泄露。因为单例的静态特性使得它的生命周期同应用的生命周期一样长,如果一个对象已经没有用处了,但是单例还持有它的引用,那么在整个应用程序的生命周期它都不能正常被回收,从而导致内存泄露。
优化方案:为了避免这样单例导致内存泄露,我们可以将 context 参数改为全局的上下文
(2)静态变量导致内存泄露:静态变量存储在方法区,它的生命周期从类加载开始,到整个进程结束。一旦静态变量初始化后,它所持有的引用只有等到进程结束才会释放
优化方案:静态持有很多时候都有可能因为其使用的生命周期不一致而导致内存泄露,所以我们在新建静态持有的变量的时候需要多考虑一下各个成员之间的引用关系,并且尽量少地使用静态持有的变量,以避免发生内存泄露。我们也可以在适当的时候讲静态量重置为 null,使其不再持有引用,这样也可以避免内存泄露
(3)非静态内部类导致内存泄露:非静态内部类(包括匿名内部类)默认就会持有外部类的引用,当非静态内部类对象的生命周期比外部类对象的生命周期长时,就会导致内存泄露
优化方案:般都会采用静态内部类+弱引用的方式
(4)资源未关闭或释放导致内存泄露:
优化方案:在使用 IO、File 流或者 Sqlite、Cursor 等资源时要及时关闭。这些资源在进行读写操作时通常都使用了缓冲,如果及时不关闭,这些缓冲对象就会一直被占用而得不到释放,以致发生内存泄露。因此我们在不需要使用它们的时候就及时关闭,以便缓冲能及时得到释放,从而避免内存泄露
(5)未取消注册或回调导致内存泄露
优化方案:在Activity或者Fragment销毁的时候取消注册或回掉
(6)Timer 和 TimerTask 导致内存泄露
优化方案:在Activity 销毁的时候要立即 cancel 掉 Timer 和 TimerTask
(7)属性动画造成内存泄露
优化方案:在 Activity或者Fragment销毁的时候 cancel 掉属性动画,避免发生内存泄漏
(8)WebView 造成内存泄露
优化方案:在 Activity 销毁后要调用它的 destory()方法来销毁它以释放内存,另外在Android5.1之后,Webview 下面的 Callback 持有 Activity 引用,造成 Webview 内存无法释放,即使是调用了Webview.destory()等方法都无法解决问题,最终的解决方案是:在销毁 WebView 之前需要先将 WebView 从父容器中移除,然后在销毁 WebView
稍后补上代码
参考:Android内存优化------常见内存泄漏以及优化方案