快捷搜索: 王者荣耀 脱发

内存泄漏与内存溢出的原因及解决方案

什么是内存泄漏、内存溢出?

内存泄漏(Memory leak):当一个对象不在使用了,本应该被垃圾回收器(JVM)回收,但是这个对象由于被其他正在使用的对象所持有,造成无法被回收的结果,通俗点就是系统把一定的内存值A借给程序,但是系统却收不回完整的A值,那就是内存泄漏。

以发生的方式来分类,内存泄漏可以分为4类: 1. 常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。 2. 偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。 3. 一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。比如,在类的构造函数中分配内存,在析构函数中却没有释放该内存,所以内存泄漏只会发生一次。 4. 隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。

内存溢出(Out of memory):系统会给每个APP分配内存也就是Heap size值,当APP所需要的内存大于了系统分配的内存,就会造成内存溢出;就是程序A找系统借内存实例化对象,但是系统没有那么多内存可借。导致功能实现失败。这就是内存溢出。

内存泄漏是造成内存溢出(OOM)的主要原因,因为系统分配给每个程序的内存也就是Heap size的值都是有限的,当内存泄漏到一定值的时候,最终会发生程序所需要的内存值加上泄漏值大于了系统所分配的内存额度,就是触发内存溢出。

Android中内存泄漏、内存溢出的原因以及解决方案

1、大量的图片、音频、视频处理,当在内存比较低的系统上也容易造成内存溢出

    建议使用第三方,或者JNI来进行处理

2、Bitmap对象的不正确处理(内存溢出)

    不要在主线程中处理图片 使用Bitmap对象要用recycle释放

3、非静态匿名内部类Handler由于持有外部类Activity的引用所造成的内存泄漏

    根据WeakReference对象,对handler使用弱引用,并且调用removeCallbacksAndMessages移除

4、线程由于匿名内部类runnable持有activity的引用,从而关闭activity,线程未完成造成内存泄漏

    把线程改成静态内部类,调用WeakReference来持有外部资源

5、BraodcastReceiver、File、Cursor等资源的使用未及时关闭

    在销毁activity时,应该及时销毁或者回收

6、static关键字修饰的变量由于生命周期过长,容易造成内存泄漏

    尽量少使用静态变量,一定要使用要及时进行制null处理

7、单列模式造成的内存泄漏,如context的使用,单列中传入的是activity的context,在关闭activity时,activity的内存无法被回收,因为单列持有activity的引用

    在context的使用上,应该传入application的context到单列模式中,这样就保证了单列的生命周期跟application的生命周期一样 单列模式应该尽量少持有生命周期不同的外部对象,一旦持有该对象的时候,必须在该对象的生命周期结束前制null
经验分享 程序员 微信小程序 职场和发展