http://blog.csdn.net/feixiaoxing/article/details/6746335node
在 咱们我的编程的过程中,内存泄露虽然不会像内存溢出那样形成各类莫名奇妙的问题,可是它的危害也是不可忽视的。一方面,内存的泄露致使咱们的软件在运行 过程当中占用了愈来愈多的内存,占有资源而又得不到及时清理,这会致使咱们程序的效率愈来愈低;另外一方面,它会影响咱们用户的体验,失去市场的竞争能力。编程
常见的内存泄露是这样的:缓存
如上图所示,咱们在函数process的处理过程当中,每一次都须要对内存进行申请,可是在函数结束的时候却没有进行释放。若是这样的一段代码出如今业务 侧,那么后果是不可思议的。举个例子来讲,若是咱们服务器每秒钟须要接受100个用户的并发访问,每一个用户过来的数据,咱们都须要本地申请内存从新保存一 份。处理结束以后,若是内存没有获得很好地释放,就会致使咱们服务器可用的物理内存愈来愈少。一旦达到某一个临界点以后,操做系统不得不经过内外存的调度 来知足咱们申请新内存的需求,这在另外一方面来说又会下降服务器服务的质量。服务器
内存泄露的危害是不言而喻的,可是查找内存泄露倒是一件苦难并且复杂的工做。咱们都知道,解决bug是一件很是简单的事情,可是寻找bug的出处倒是一 件很是吃力的事情。所以,咱们有必要在本身编写代码的时候,就把查找内存泄露的工做放在很重要的位置上面。那么有没有什么办法来解决这一问题呢?数据结构
我想要作到解决内存泄露,必须作到下面两个方面:并发
(1)必须记录内存在哪一个函数申请的,具体文件的行数是多少函数
(2)内存应该何时被释放测试
要完成第1个条件其实并不困难。咱们能够用节点的方法记录咱们申请的内存:spa
a)设置节点的数据结构操作系统
其中 functionName记录函数名称,line记录行数, pAddress记录分配的地址, next记录下一个内存节点。
b)修改内存的分配函数
对业务侧的malloc进行函数修改,添加下面一句宏语句
#define malloc(param) MemoryMalloc(__FUNCTION__, __LINE__, param)
在桩函数侧书写下面的代码
内存的分配过程当中还涉及到了节点的添加,因此咱们还须要添加下面的代码
文中gMemNode表示全部内存节点的根节点,咱们每增长一次malloc过程就会对内存节点进行记录。在记录过程当中,咱们还会记录调用malloc的函数名称和具体文件行数,这主要是为了方便咱们在后面进行故障定位的时候更好地查找。
完成了第一个条件以后,咱们就要对第二个条件进行完成。
a)内存何时释放,这取决于咱们在函数中是怎么实现的,可是咱们在编写测试用例的时候倒是应该知道内存释放没有,好比说若是测试用例所有结束了,咱们有理由相信assert(gMemNode == NULL)这应该是恒等于真的。
b)内存释放的时候,咱们应该作些什么?和节点的添加同样,咱们在内存释放的时候须要free指定的内存,free节点,free节点的内存,下面就是在释放的时候咱们须要进行的操做
对业务侧的free函数进行修改,添加下面一句宏代码,
#define free(param) MemoryFree(param)
在桩函数侧输入下面的代码:
在删除内存的时候,须要删除节点,删除节点的内存
有了上面一小段代码的帮助,咱们在编写测试用例的时候,就能够在函数执行后,经过判断内存节点是否为空的方法判断内存是否已经释放。若是内存没有释放,咱们还能经过节点的信息帮助咱们是哪里发生了错误,可是这个方法还有两个缺点:
(1)没有考虑缓存的状况,好多内存分配了以后并不会在函数中立刻释放,而是放在缓存池中等待下一次调用,这就须要咱们准确把握和判断了。
(2)代码中节点删除和添加的时候没有考虑多进程的情形,应该考虑用一个互斥锁或者是信号量加以保护。