C/C++因爲靈活、高效的優勢一直以來都是主流的程序設計語言之一,可是其內存的分配與釋放均由程序員本身管理,當因爲疏忽或錯誤形成程序未能釋放再也不使用的內存時就會形成內存泄漏。在大型、複雜的應用程序中,內存泄漏每每是最多見的問題,於是及時解決內存泄漏很是必要。tMemMonitor (TMM)做爲一個專業、準確、易用的內存泄漏分析工具,能夠幫助C/C++程序員迅速地解決內存泄漏這個使人頭疼的問題。程序員
TMM下載地址(中文版): http://download.csdn.net/detail/tmemmonitor/9444634 算法
TMM下載地址(英文版): http://download.csdn.net/detail/tmemmonitor/9444660安全
一.背景函數
目前市面上已有一些Windows平臺下的內存泄漏動態檢測工具,好比UMDH,VLD,Purify,BoundsCheck等,其中Purify和BoundsCheck是昂貴的商用軟件,UMDH須要人工獲取內存快照,操做門檻較高,VLD則須要修改源程序的代碼,同時這幾款工具都存在誤報狀況,所以準確性不高。針對Windows平臺,C/C++程序員迫切須要一款專業、準確、易用的內存泄漏分析工具。工具
二.TMM簡介佈局
TMM是一款運行時C/C++內存泄漏檢測工具。TMM認爲在進程退出時,堆內存中沒有被釋放且沒有指針指向的無主內存塊即爲內存泄漏,並進而引入垃圾回收(GC, Garbage Collection)機制,在進程退出時檢測出堆內存中全部沒有被引用的內存單元,於是內存泄露檢測準確率爲100%。post
TMM工具主要包含兩部分,第一部分是客戶端的檢測界面,客戶端部分主要負責監控目標進程中的內存行爲並計算內存泄漏。檢測時只要將被檢測程序添加到監控列表中,而後正常運行被檢程序便可,如下爲客戶端界面:性能
另外一部分是結果的展現與分析。TMM支持本地查看和在線查詢兩種方式。本地查看時,提供按泄漏次數或泄漏大小對結果進行排序的功能,並在安裝目錄的data文件夾中給出詳細分析報告。用戶也可憑QQ賬號登陸WeTest網站對內存泄漏狀況進行在線查詢。如下爲本地查看結果:網站
三.TMM的特性和優勢.net
專業
Ø 最快的注入技術
Ø 基於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),該算法的核心就是檢測(掃描)沒有任何指針指向的堆內存,具體分爲五步:
Step 1. 進程退出時,suspend全部線程,防止數據在掃描過程當中更改。假設此時進程中的堆內存佈局如圖2所示;
圖2
Step 2. 統計root-set,它由每一個線程的寄存器、全部非堆內存、全部線程棧幀頂部RSP/ESP以上區域、全部庫的數據區組成;
Step 3. 從root-set出發遍歷圖2,標記出有指針指向的內存塊,即beginning reachable blocks,如圖3中A、C;
圖3
Step 4. 因爲beginning reachable blocks也會包含有指針,所以經過遍歷beginning reachable blocks能夠找出其內部指針指向的內存塊並標記,如圖4中B;
圖4
Step 5. 統計檢測出來的內存泄漏,即圖4中unreachable的堆內存塊D、E、F。
五.使用步驟
圖5
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://download.csdn.net/detail/tmemmonitor/9444634
TMM下載地址(英文版): http://download.csdn.net/detail/tmemmonitor/9444660
QQ支持: 2304186838
聯繫Email: 2304186838@qq.com