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不匹配 检测栈 ...
随机推荐
- j2ee概览
J2EE诞生的背景是什么?Java 2平台企业版,也就是J2EE,定义了开发多层企业应用程序的标准.它的诞生并不是偶然的,它是在各种条件积累成熟之下的产物.原因之一:java语言的巨大成功.1994年 ...
- Fatal error: Allowed memory size of 8388608 bytes exhausted
这两天安装bugfree,更换了一个数据量较大的库,结果打开bug详情页要么是空白页,要么就报如题的错误,错误信息还包括C:\wamp\www\bugfree\Include\Class\ADOLit ...
- Linux下(主要针对Ubuntu)下桌面分辨率的添加
系统版本: Linux (Ubuntu) 其他桌面发行版应该也行. 相关命令: lspci, cvt, xrandr 在桌面分辨率不正常显示桌面或者没有最佳的分辨率时,需要修改添加适合的桌面分辨率模式 ...
- UESTC_Islands 2015 UESTC Training for Data Structures<Problem J>
J - Islands Time Limit: 30000/10000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Su ...
- Windows多线程同步系列之一-----互斥对象
多线程同步之互斥对象 作者:vpoet mail:vpoet_sir@163.com 对卖票问题进行线程间同步,本文将在上文的基础上,使用互斥对象对线程进行同步. 首先看看windows API ...
- python hook监听事件
python hook监听事件 作者:vpoet mail:vpoet_sir@163.com # -*- coding: utf-8 -*- # # by oldj http://oldj.net/ ...
- 使用ASIHttoRequest需要导入的framework
需要导入如下framework libxml2.2.dylib libz.1.2.5.dylib MobileCoreServices.framework SystemConfiguration.fr ...
- 实现一次请求加载多个js或者css
http://tengine.taobao.org/ 相当牛x
- 随机函数(Pascal入门)
随机函数是最主要的,在比赛的时候我们能够用随机函数来測试自己的程序是否会超时. 随机函数也能够做出一些大数据.用于两个程序之间对拍(一个是爆搜.一个是正解). 当然平时我们也能够用随机函数測自己的程序 ...
- 【DataStructure】Some useful methods about linkedList(二)
Method 1: Add one list into the other list. For example, if list1is {22, 33, 44, 55} and list2 is { ...