Android 内存泄漏

一、什么是内存泄漏

内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放, 造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

简单的说也就是程序中动态分配的内存因为某种特殊原因无法清除,造成的内存浪费没有回收一直占用会导致内存泄漏。

就是你只添加而不去清除,最后越攒越多,造成内存浪费


二、有哪些情况会导致内存泄漏切如何解决

1.集合类泄漏

集合如果只有添加元素的方法,没有相应的删除机制,就会到之后内存被占用。如果这个集合是全局的变量,没有相应的删除机制,就会导致集合占用的内存只增加不减。

2.单例造成的内存泄漏

单列的静态特性的生命周期和应用的生命周期一样长,如果使用不恰当,就会造成内存泄露。

3.匿名内部类/非静态内部类和异步线程

非静态内部类创建静态实例造成的内存泄漏

4.匿名内部类

Android 开发经常会继承继承实现activity、fragment、view,如果使用了匿名类,就异步线程持有,没有任何措施就会内存泄漏。

5.Handler 造成的内存泄漏

handler、message和messageQueue都是相互关联在一起的,万一handler发送的message没有被处理,message和发送的handler对象被线程messagequeue一直持有。handler属于tls变量,生命周期和view,activity是不一致的,导致无法正常释放。

6.尽量避免使用 static 成员变量

如果你的app进程设计上是长驻内存的,那即使app切到后台,这部分内存也不会被释放。按照现在手机app内存管理机制,占内存较大的后台进程将优先回收,yi'wei如果此app做过进程互保保活,那会造成app在后台频繁重启。当手机安装了你参与开发的app以后一夜时间手机被消耗空了电量、流量,你的app不得不被用户卸载或者静默。

7.避免 override finalize()

8.资源未关闭造成的内存泄漏

对于使用了BraodcastReceiver,ContentObserver,File,游标 Cursor,Stream,Bitmap等资源的使用,应该在Activity销毁时及时关闭或者注销,否则这些资源将不会被回收,造成内存泄漏。

9.一些不良代码造成的内存压力



三、如何检测内存泄漏

 1.使用调试器和C运行库(CRT)调试堆函数。 

2.养成良好的代码习惯 

3 内存泄露就是指在程序中出现动态分配的内存单元,使用结束后没有释放的情况。

 4调试运行时,内存泄露一般屏幕上会现现memory leak字样的英文。

5.可以使用LeakCanary 分析内存泄漏。在百度搜可以集成


四、什么是内存溢出和解决办法

什么是内存溢出:

      1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据;

  2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;

  3.代码中存在死循环或循环产生过多重复的对象实体;

  4.使用的第三方软件中的BUG;

  5.启动参数内存值设定的过小;

溢出的解决方法:

【情况一】:

java.lang.OutOfMemoryError:Javaheapspace:这种是java堆内存不够,一个原因是真不够(如递归的层数太多等),另一个原因是程序中有死循环;

  如果是java堆内存不够的话,可以通过调整JVM下面的配置来解决:

  -Xms3062m

  -Xmx3062m

【情况二】

  java.lang.OutOfMemoryError:GCoverheadlimitexceeded

  【解释】:JDK6新增错误类型,当GC为释放很小空间占用大量时间时抛出;一般是因为堆太小,导致异常的原因,没有足够的内存。

  【解决方案】:

  1、查看系统是否有使用大内存的代码或死循环;

  2、通过添加JVM配置,来限制使用内存:

  -XX:-UseGCOverheadLimit

【情况三】:

  java.lang.OutOfMemoryError:PermGenspace:这种是P区内存不够,可通过调整JVM的配置:

  -XX:MaxPermSize=128m

  -XXermSize=128m

  【注】:

  JVM的Perm区主要用于存放Class和Meta信息的,Class在被Loader时就会被放到PermGenspace,这个区域成为年老代,GC在主程序运行期间不会对年老区进行清理,

  默认是64M大小,当程序需要加载的对象比较多时,超过64M就会报这部分内存溢出了,需要加大内存分配,一般128m足够。

【情况四】:

  java.lang.OutOfMemoryError:Directbuffermemory

  调整-XX:MaxDirectMemorySize=参数,如添加JVM配置:

  -XX:MaxDirectMemorySize=128m

【情况五】:

  java.lang.OutOfMemoryError:unabletocreatenewnativethread

  【原因】:Stack空间不足以创建额外的线程,要么是创建的线程过多,要么是Stack空间确实小了。

  【解决】:由于JVM没有提供参数设置总的stack空间大小,但可以设置单个线程栈的大小;而系统的用户空间一共是3G,

       除了Text/Data/BSS/MemoryMapping几个段之外,Heap和Stack空间的总量有限,是此消彼长的。因此遇到这个错误,

        可以通过两个途径解决:1.通过-Xss启动参数减少单个线程栈大小,这样便能开更多线程(当然不能太小,太小会出现StackOverflowError);

                  2.通过-Xms-Xmx两参数减少Heap大小,将内存让给Stack(前提是保证Heap空间够用)。

【情况六】:

  java.lang.StackOverflowError

  【原因】:这也内存溢出错误的一种,即线程栈的溢出,要么是方法调用层次过多(比如存在无限递归调用),要么是线程栈太小。

  【解决】:优化程序设计,减少方法调用层次;调整-Xss参数增加线程栈大小

(2) 在使用内存之前检查指针是否为NULL。假设指针p 是函数的參数,那么在函数的入口处用assert(p!=NULL)进行检查。假设是用malloc 或new 来申请内存,应该用if(p==NULL)或if(p!=NULL)进行防错处理。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 一、什么是内存泄漏 内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放...
    df22a1577cea阅读 192评论 0 0
  • 内存溢出和内存泄露的概念 内存溢出 out of memory指程序在申请内存时,没有足够的内存空间供其使用,出现...
    MengkZhang阅读 3,782评论 1 9
  • 内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memo...
    XX杰阅读 659评论 0 0
  • 内存抖动、内存溢出、内存泄漏 内存抖动在极短的时间内,分配大量的内存,然后又释放它,这种现象就会造成内存抖动。典型...
    qiaoStr阅读 536评论 0 6
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,865评论 16 22

友情链接更多精彩内容