Memory Leak(内存泄漏)问题总结(转)
最近听了一些关于Memory Leak(内存泄漏)的seminar,感觉有些收获,所以留个记录,并share给朋友。
1 什么是Memory Leak。 Memory Leak是指由于错误或不完备的代码造成一些声明的对象实例长期占有内存空间,不能回收。Memory Leak会造成系统性能下降,或造成系统错误。
2 Memory存储模式 我们通常写的C++或Java Code在内存里边的存储状况概如下图。

简单的说,一般局部变量存储于Stack中,以提高运行问速度。而New出来的变量则将引用信息或指针存储在Stack中,而将对象本身存储与Heap区中。
这里感谢俊晓同学看完blog后提供了这如下link,可以让大家更好的理解什么堆啊,栈啊之类的概念。
http://www.builder.com.cn/2007/1010/544483.shtml
3 编码产生Memory Leak的原因,及避免
Memory Leak的原因现归纳出3种,以后要还有,再做补充。
(1)No Referenced Memory (C++ only)
Sample 1 a(){
DKString* s= new DKString();
… …
… …
delete s;
}
Sample 2 a(){
char* buffer = (char*)malloc(64 * sizeof(char);
… …
… …
free(buffer);
}
C++里边生成/释放变量的方式有两种,new/delete, malloc()/free()。无论用那种方式生成,最后一定要有释放的动作。
否则,在程序离开变量作用域时,Stack里边的引用会被自动回收,但Heap里的对象实例本身就将成为被永久遗弃在内存里的No Referenced Memory。
另外需要注意的是, 如果用new生成的,一定要用delete释放;
如果用malloc生成的,一定要用free释放。反之,虽然代码可以通过编译,但是会造成很多潜在问题。
(2)No free Objects/Pointers (C++ and Java)
Java比C++方便的地方是Java可以自圾回收已经过期的内存垃圾,GC。所以,Java程序员从不用关心delete还是free的问题。
但是碰到下面这种情况,GC也无能为力,更不要说C++了。
Sample 3
String[] sa = new String[9999999];
for (int i = 0; i < 9999999; i++){
String s = new String(“adfasdfadsfas…adfasdfa”); //a 1MB size string…
sa[i] = s;
}
这段代码让GC郁闷的是,当循环结束之前,GC永远收不到任何空间。
因为GC只能收集那些过期的变量,可是在sa过期之前,可能OutOfMemory已经发生了。
(3)No Limited Storage (C++ and Java)
Sample 4 … …
While (true){
Vector.add(obj);
}
… …
像 Vector, hashtable, hashmap, map, arraylist and String StringBuffer… …这样的工具类自身没有上限,如果,Developer再不加控制,很容易内存溢出。
4 如何通过测试发现Memory Leak
(1)Long Run
很多时候,微小的Memory Leak不会给我们的系统造成太多的影响,只有当泄露积累到一定程度,问题才会爆发。因此,从理论上说,我们要让代码多次重复的Run从而暴露Memory Leak问题。在我们公司,这种测试叫Long Run。所谓Long Run并不一定说一定要让测试Case跑多么长的时间,而是跑足够的次数。
(2)特殊Case
这是一个Tester的经验做法,他们相信developer会在大部分正常的程序逻辑里边考虑和处理Memory Leak问题,但异常条件也许未必,所以,通过适当的临界测试和特殊case测试,亦或能找到Memory Leak的case.
个人认为,发现并避免Memory Leak,最重要的还是Developer从程序设计、编码的时候就在上游把好质量关。否则,真正到Tester发现并定位Memory Leak问题,代价则相当大。
5 分析Memory Leak的工具
工欲善其事,必先利其器。这里会搜及并不断补充一些Memory Leak的分析工具,以满足Tool People的要求。
(1)Purify 一般For C Code
(2)Heap Analyzer
可以For Java Code
(3)Java Dump
这牵涉到另一个Topic,希望以后能有所补充。
http://blog.csdn.net/iloveagile/article/details/3850668
汗死,把内存溢出和内存泄漏混为一谈了,后面两种情况不属于内存泄漏,而是内存溢出。
内存泄漏通俗的讲是指某个程序申请了某块内存,不用了以后,没有回收,系统以为该内存还是被占用的,因此该内存【相当于】消失了。
而内存溢出则是程序在申请内存时,没有足够的内存空间供其使用。
二者之间的联系是:内存泄漏如果累积最终也会造成内存溢出
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。
内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
memory leak会最终会导致out of memory!
内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。
内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。一个盘子用尽各种方法只能装4个果子,你装了5个,结果掉倒地上不能吃了。这就是溢出!
比方说栈,栈满时再做进栈必定产生空间溢出,叫上溢,栈空时再做退栈也产生空间溢出,称为下溢。就是分配的内存不足以放下数据项序列,称为内存溢出.
以发生的方式来分类,内存泄漏可以分为4类:
1. 常发性内存泄漏。
发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。
2. 偶发性内存泄漏。
发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。
常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。
所以测试环境和测试方法对检测内存泄漏至关重要。
3. 一次性内存泄漏。
发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。
比如,在类的构造函数中分配内存,在析构函数中却没有释放该内存,所以内存泄漏只会发生一次。
4. 隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。
严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。
但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。
所以,我们称这类内存泄漏为隐式内存泄漏。
从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在。
真正有危害的是内存泄漏的堆积,这会最终消耗尽系统所有的内存。
从这个角度来说,一次性内存泄漏并没有什么危害,因为它不会堆积,而隐式内存泄漏危害性则非常大,因为较之于常发性和偶发性内存泄漏它更难被检测到
http://blog.csdn.net/buutterfly/article/details/6617375
Memory Leak(内存泄漏)问题总结(转)的更多相关文章
- 转: 利用 DEBUG_NEW 来追溯 Memory leak 内存泄漏
参考: https://msdn.microsoft.com/en-us/library/tz7sxz99.aspx http://www.cnblogs.com/taoxu0903/archive/ ...
- MFCButton Memory leak(内存泄露问题)
http://m.blog.csdn.net/blog/haoekin/8851219 1.无法显示右边箭头的问题 无论怎么折腾都没显示不出来,微软给的示例又能显示,度娘和谷歌也都不知道,经过不断地探 ...
- Dynamically allocated memory 动态分配内存【malloc】Memory leaks 内存泄漏
内存泄露Memory leaks :没有指针指向原来a分配出来的那段空间了
- Java 基础 - 内存泄露Memory leak & 内存溢出Out of memory
内存泄露 & 内存溢出 关系 https://www.cnblogs.com/panxuejun/p/5883044.html 内存泄露的6种情况: https://blog.csdn.net ...
- DTrace memory leak 内存泄露
http://blog.sina.com.cn/s/blog_538040b70100eecn.html 如下程序用于跟踪,在分配和回收都会触发探针 #!/usr/sbin/dtrace -s p ...
- Linux C/C++ Memory Leak Detection Tool
目录 . 内存使用情况分析 . 内存泄漏(memory leak) . Valgrind使用 1. 内存使用情况分析 0x1: 系统总内存的分析 可以从proc目录下的meminfo文件了解到当前系统 ...
- 警告: The web application [ROOT] appears to have started a thread named [Thread-48] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
1. 问题描述 tomcat跑web项目(其中依赖java项目) 出现大量上述警告 项目起不来 关键字 memory leak 内存泄漏 2. 解决方案 难道是程序写的有问题? 最终 将tomcat ...
- [Android随笔]内存泄漏以及内存溢出
名词解释 内存泄漏:memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄漏危害能够忽略,但内存泄漏堆积后果非常严重,不管多少内存,迟早会被占光. 内存溢出:out of ...
- MAT分析android内存泄漏
转载请标明出处:https://www.cnblogs.com/tangZH/p/10955429.html 泄漏,泄漏,漏~ 内存泄漏怎么破,什么是内存泄漏?与内存溢出有什么区别? 内存泄漏(Mem ...
- 面向开发的内存调试神器,如何使用ASAN检测内存泄漏、堆栈溢出等问题
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 目录 介绍 如何使用 ASAN 检测内存泄漏 检测悬空指针访问 检测堆溢出 C++ 中的new/delete不匹配 检测栈 ...
随机推荐
- 折腾gnome3.4
1.平埔式窗口管理器shellshape 刚开始用都是登录时默认为gnome classic,主要是希望有任务栏,但是为了在这种模式,gnome扩展都没有用了. 而我又在使用shellshape -- ...
- 在 .NET Framework 2.0上使用LINQ
附件:System.Linq.dll.7z 此为从System.Core.dll中剥离的Linq,含有System.Linq.Enumerable类所有扩展方法,可以在客户只安装了.Net 2.0的环 ...
- 使用fragment,Pad手机共用一套代码
项目代码结构: 1:MainActivity.java package com.example.fgtest; import android.app.Activity; import android. ...
- Ext4 MVC CRUD操作
项目目录结构如下: (1)index.html <!DOCTYPE html> <html> <head> <title>用户管理</title& ...
- Gson的简单使用
package test; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import java.uti ...
- hdu 1466 计算直线的交点数
http://acm.hdu.edu.cn/showproblem.php?pid=1466 N条直线的交点方案数 = c 条直线交叉的交点数与(N-c)条平行线 + c 条直线本身的交点方案 = ( ...
- 压缩、解压缩流GZipStream
如果要在压缩过程中检查错误或要与其他操作系统所用程序共享压缩数据,则要是用GZipStream类.GZipStream类包含是用GZip数据格式进行压缩和解压缩文件的方法,该类不能用于解压缩大于4GB ...
- jquery中使用offset()获得的div的left=0,top=0
写东西的时候要获取div的left和top,但怎么也取不到值都为0,但在chrome的console下是可以取到值的, 瞬间就纳闷了,于是乎就在网上找各种方法,大家一般的问题可能都是要获取的div被隐 ...
- 几个js的linq实现
几个js的linq实现 linqjs.codeplex.com jslinq.codeplex.com javascriptiqueryable.codeplex.com fromjs.codeple ...
- poj 2411 新写法
别以为我在刷水题.... 今天做了场srm,500pt想到了是dp但是无从下手,但是看了rng_58的神代码后顿觉海阔天空啊(盯着看了一个下午),相比于一年前的写法,真的是不忍直视啊, TC真是个好地 ...