C/C++因为灵活、高效的优势一直以来都是主流的程序设计语言之一,可是其内存的分配与释放均由程序员本身管理,当因为疏忽或错误形成程序未能释放再也不使用的内存时就会形成内存泄漏。在大型、复杂的应用程序中,内存泄漏每每是最多见的问题,于是及时解决内存泄漏很是必要。tMemMonitor (TMM)做为一个专业、准确、易用的内存泄漏分析工具,能够帮助C/C++程序员迅速地解决内存泄漏这个使人头疼的问题。程序员
TMM中文版下载地址: http://down.51cto.com/data/2184722算法
TMM英文版下载地址: http://down.51cto.com/data/2184729安全
一.开发背景ide
目前市面上已有一些Windows平台下的内存泄漏动态检测工具,好比UMDH,VLD,Purify,BoundsCheck等,其中Purify和BoundsCheck是昂贵的商用软件,UMDH须要人工获取内存快照,操做门槛较高,VLD则须要修改源程序的代码,同时这几款工具都存在误报状况,所以准确性不高。针对Windows平台,C/C++程序员迫切须要一款专业、准确、易用的内存泄漏分析工具。函数
二.TMM简介工具
TMM是一款运行时C/C++内存泄漏检测工具。TMM认为在进程退出时,堆内存中没有被释放且没有指针指向的无主内存块即为内存泄漏,并进而引入垃圾回收(GC, Garbage Collection)机制,在进程退出时检测出堆内存中全部没有被引用的内存单元,于是内存泄露检测准确率为100%。布局
TMM工具主要包含两部分,第一部分是客户端的检测界面,客户端部分主要负责监控目标进程中的内存行为并计算内存泄漏。检测时只要将被检测程序添加到监控列表中,而后正常运行被检程序便可,如下为客户端界面:post
另外一部分是结果的展现与分析。TMM支持本地查看和在线查询两种方式。本地查看时,提供按泄漏次数或泄漏大小对结果进行排序的功能,并在安装目录的data文件夹中给出详细分析报告。用户也可凭QQ账号登陆WeTest网站对内存泄漏状况进行在线查询。如下为本地查看结果:性能
三.TMM的特性和优势网站
专业
最快的注入技术
基于GC的精准算法,无需内存快照
无损目标程序性能
检测结果精准定位到代码堆栈信息
准确
二次遍历堆内存对象里的指针
寄存器级的问题跟踪,完整扫描每一个线程里32位寄存器内的指针
不放过全局数据区里的内容
易用
支持自定义程序
无须编译,当即使用
一键操做,无需切换
四.算法原理
1. 替换/注入堆内存分配函数的算法
Windows中有多种级别的内存分配函数,其中,最底层的是ntdll.dll提供的Rtl系列函数,在这之上的有Windows API提供的heap管理函数,再上层,C/C++库提供了malloc/free函数和new/delete操做符,所以替换如此层级复杂的函数比较困难,同时若是替换现有的堆分配函数,则没法作到和原有函数的执行效果彻底一致,因此替换原生的堆分配函数对于Windows系统来讲几乎是不可行的,那么只能wrap(包裹)这些堆分配函数。
Linux下的内存检测工具,好比Valgrind就采用了包裹堆分配函数的方法,但它包裹的方法是不透明的,在调用栈中会多出额外一帧。TMM则采用全透明的包裹函数,将挂钩函数分为先后二部分(如图1所示)。在函数调用前执行per-hook函数,在函数返回前调用执行post-hook函数。有了先后挂钩函数,TMM就能够在堆分配/释放函数执行前得到参数,并修改分配大小之类的参数;在函数执行后,记录分配的大小和地址、调用栈之类的信息。
图1
2. 泄露检测的算法
TMM使用基于堆内存可访问性的内存泄露检测法( reachability-based leak detection),该算法的核心就是检测(扫描)没有任何指针指向的堆内存,具体分为五步:
Step1. 进程退出时,suspend全部线程,防止数据在扫描过程中更改。假设此时进程中的堆内存布局如图2所示;
图2
Step2. 统计root-set,它由每一个线程的寄存器、全部非堆内存、全部线程栈帧顶部RSP/ESP以上区域、全部库的数据区组成;
Step3. 从root-set出发遍历图2,标记出有指针指向的内存块,即beginning reachable blocks,如图3中A、C;
图3
Step4. 因为beginning reachable blocks也会包含有指针,所以经过遍历beginning reachable blocks能够找出其内部指针指向的内存块并标记,如图4中B;
图4
Step5. 统计检测出来的内存泄漏,即图4中unreachable的堆内存块D、E、F。
五.使用步骤
1. 在拥有Administrator权限的状况下启动TMM。
2. 在列表区右键添加程序,正常操做。
3. 正常退出被添加程序。
4. 耐心等待检测结果生成(程序状态由running变为null时,说明程序正常退出,检测结果生成完毕)。
5. 查看结果。
六.注意事项
1. 安装TMM时,用户应具备Administrator权限,而且TMM不支持中文安装路径。
2. 使用TMM时须要修改注册表,如遇安全软件弹窗警告,可将TMM加入信任列表放心使用。
3. 被检测程序不能是加壳版本,由于加壳程序的函数名和函数地址已经混淆。
4. 被检测程序需是release版本。
5. 如需在分析报告中显示泄漏点详细堆栈信息,请在被检测程序同级目录放置同版本的PDB文件,PDB解析时目录不支持中文。
6. 使用TMM致使被测程序退出时变慢属于正常状况,此时TMM正在统计内存泄漏状况,请不要手动强制结束进程。
七.总结
TMM适用于PC端全部C/C++程序的内存泄漏分析。对于被测程序,不须要修改源代码,运行一次被测程序就可以准肯定位泄漏的文件名和行号。TMM是一款专业、准确、易用的内存泄漏检测工具,值得每一个程序员拥有。
TMM中文版下载地址: http://down.51cto.com/data/2184722
TMM英文版下载地址: http://down.51cto.com/data/2184729
QQ支持: 2304186838
联系Email: 2304186838@qq.com