内存泄露和内存溢出

上一篇 / 下一篇  2015-11-05 17:06:26 / 个人分类:java相关

memory leak
1.what is memory leak?
内存泄露指的是由于疏忽或错误造成程序未能释放已经不再使用的内存的情况,不是指的内存在物理上的消失,而是你的应用程序分配某段内存后,由于设计错误,失去了对这一段内存的控制,造成了内存的浪费,所以内存泄露实际应该叫内存浪费??
好比你向系统申请分配内存(new),结果你用完了不还(delete),这就搞成了你申请的这一块内存你自己用不成了,系统也用不成了,

2.对于C和C++这种没有GC(garbage collection)的语言来说,需要关注两种类型的内存泄露:

堆内存泄露:程序运行中根据需要分配通过malloc,realloc,new等语句从堆heap中分配的一块内存,在完成后必须通过对应的free或delete删除,因为程序的设计错误导致这部分内存没有被释放,那么此后这一块内存也不会再被使用了,就产生了堆内存的浪费,heap leak

系统资源泄露:这个主要指的是程序使用系统分配的资源比如Bitmap,handle,socket等等没有使用对应的相关函数释放掉,导致了系统资源的浪费,严重的会导致系统效能降低,系统运行的不稳定,这个就是rescoure leak

3.如何去解决内存泄露?

困难有以下因素:
1.编译器发现不了这些
2.运行时才能捕获到这些错误,并且这些错误明显的征兆,时隐时现
3.对于手机这种终端用户来说特别困难,

解决方式:
良好的编码习惯,使用了内存分配的函数,记得用对应的函数释放:

Heap memory:
malloc\realloc-----free
new \ new []-----delete\delete[]
GlobalAlloc-----GlobalFree

特别当心数组对象的内存泄露:

MyPointEX *pointArray =new MyPointEX [100];
      其删除形式为:
    delete []pointArray 


Resource Leak:对于系统资源使用之前要仔细看它的使用方法,防止错误使用或者忘记释放掉系统资源


有内存泄露引出内存溢出:
嘛叫内存溢出呢?就是你要求系统分配给你的内存超出了系统能给你的,系统满足不了你了,就产生了内存溢出问题,内存溢出应该叫做你要的内存欲求不满。。。。系统不能满足了。。。
比如最简单的,你申请 了一个Integer,却存一个要long才能放下的数,这就是内存溢出,我的理解,为毛说内存泄露和内存溢出存在关系呢?因为内存泄露多了,该用的都被无效占用了,到一个真正要用的地方或者需要很大内存的时候,没有足够的内存了,就发生了内存溢出


常见的溢出:
内存分配不成功,你却使用了它
内存分配成功了,但是没有初始化就使用了它
内存分配成功,但是操作的时候超过了它的边界
举个栗子:测试某app遇到的内存溢出bug:

09-02 17:05:02.937 22238 22313 E AndroidRuntime: FATAL EXCEPTION: pool-6-thread-1
09-02 17:05:02.937 22238 22313 E AndroidRuntime: Process: com.changhong.synergystorage, PID: 22238
09-02 17:05:02.937 22238 22313 E AndroidRuntime: java.lang.OutOfMemoryError: Failed to allocate a 65548 byte allocation with 30010 free bytes and 29KB until OOM
09-02 17:05:02.937 22238 22313 E AndroidRuntime: at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:676)

总的来说,内存泄露,一次内存泄露无所谓,但是它的后果很严重,无论你有多少内存,都会迟早被它占光!!
最后的结果就是memory leak----out of memory
   内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。一个盘子用尽各种方法只能装4个果子,你装了5个,结果掉倒地上不能吃了。这就是溢出!比方说栈,栈满时再做进栈必定产生空间溢出,叫上溢,栈空时再做退栈也产生空间溢出,称为下溢。就是分配的内存不足以放下数据项序列,称为内存溢出. . 

   以发生的方式来分类,内存泄漏可以分为4类: 

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

从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在。真正有危害的是内存泄漏的堆积,这会最终消耗尽系统所有的内存。从这个角度来说,一次性内存泄漏并没有什么危害,因为它不会堆积,而隐式内存泄漏危害性则非常大,因为较之于常发性和偶发性内存泄漏它更难被检测到 




TAG:

 

评分:0

我来说两句

Open Toolbar