导致内存泄漏的根本原因是因为C++没有内存回收机制gc,内存分配和内存释放次数不对等,是一个很常见的问题,常用的工具有valgrind、mtrace等等,不过这些工具的问题点是我们已经发现了内存泄漏。危害是堆上内存被耗尽,当我们想使用的时候就分配不出来,代码运行不下去被系统强行回收。
- 如何预防内存泄漏
- 如何解决内存泄漏
- 如何发现内存泄漏
分配时候计数器加1,释放时候计数器减1。当我们看到计数器不为0,正常退出的话计数器不等于0,可以大胆的推测出可能存在内存泄漏。 如何定位哪一行内存泄漏
- _FILE,FUNCTION,_LINE宏定位代码执行情况
- built_return_address() 返回函数被哪里调用的_libc_malloc()。 破除递归的方法的代码需要注意。
通过addr2line贡酒对指定地址进行代码行数定位,这个做法也是我第一次见,感觉开启了新世界的大门。
malloc时创建文件,free时删除文件,看程序最后剩下什么文件就可以直观的看到内存泄漏情况。
可以通过cat命令,将内存泄漏的地址进行查看,再通过addr2line工具对泄漏位置进行定位。
别人的库有内存泄漏怎么办?
只要它底层调用的malloc也是可行的。
在/usr/local/malloc.h __malloc_hook是一个函数指针,当调用malloc时会调用这个函数指针。相对应的也有__free_hook这个函数指针。我们重新将指针赋一个新的地址,这样就有点类似于钩子的感觉,调用malloc/free时将被我们截获。
导入库 export MALLOC_TRACE=./test.log 否则日志文件无法生成。需要把分配释放的地址进行对应分析,然后找出落单的,再用add2line工具计算出具体的泄漏行数,和上面三种方法有异曲同工之妙。
首先,不要认为内存泄漏这个问题复杂,核心主要两个问题。如果发现内存泄漏,发现泄漏找到具体出错位置,对错误进行排查。虽然认真学了一上午,感觉还是有些收获,但是在代码层面上还需要进一步加强。从另一个角度来说,尽然C++11封装了智能指针,还是应该充分的使用智能指针,要不然内存泄漏真的是让人头痛的一个事啊!
共享内存mmap shmget
用户空间内专门有一个地方所谓的共享内存,在task_struct结构体中的mm_struct结构体中,堆栈,代码段数据段,参数环境变量等等都整洁的排布着。进程初始化时将各个数值进行赋,mmap_base是共享内存的初始值。值得注意的是,共享内存不是在堆栈上,是有一块虚拟的空间,不同的进程映射在相同的内存空间。有点匿名管道的意思。
原文作者:屯门山鸡叫我小鸡