標籤:第一個 windows系統 note fast 詳細資料 expected div window stack
FastMM 定位記憶體泄露的代碼位置
開源的FastMM,使用很簡單,在工程的第一行引用FastMM4即可(注意,一定要在第一個Uses的位置),可以在偵錯工具時提示記憶體泄露情況,還可以產生報告。
在Delphi2007以後版本中,使用更加簡單,只需要在工程開始的位置加上語句:
ReportMemoryLeaksOnShutdown := True;就可以了,並且在運行時不會出現提示。如果想要組建檔案報告,還需要FastMM4,Delphi中沒有別的設定可以組建檔案報告。
可以修改FastMM4Options.inc中的參數開關來修改記憶體管理的相關設定。
使用說明如下:
1.開啟FastMM4的調試功能
首先在自己的project裡把FastMM4放在最前面,例如:
FastMM4,
Main in ‘Main.pas’ {MainForm},
再修改FastMM4Options.inc,開啟全偵錯模式。例:
{$define FullDebugMode}
也可以在project中定義編譯常量:FullDebugMode。
同時把FastMM_FullDebugMode.dll拷貝到編譯後產生的可執行程式所在目錄。
再要開啟記憶體流失報告:EnableMemoryLeakReporting。一般情況下是預設開啟的。 這樣就開啟了全偵錯模式,如果發生記憶體流失將會產生報告檔案,如果在IDE啟動並執行時候還會彈出一個對話方塊顯示。報告檔案類似:XXX_MemoryManager_EventLog.txt
2.報告檔案由兩部分組成,並且是每次運行append。
第一部分是泄漏的詳細內容,將每個沒釋放的記憶體塊詳細資料顯示出來。例:
A memory block has been leaked. The size is: 28
{一個28位元組的記憶體塊在程式結束後沒有被釋放}
{這個記憶體塊在分配的時候的呼叫堆疊,也就是Call Stack,可以清楚看出調用函數的次序。如果是系統dll則還有相應的函數名。}
Stack trace of when this block was allocated (return addresses):
4028E7
4030EC
406649
412365
41236E
411DD3
426B45
427236
42888C
{這個記憶體類型,如果是字串string或TObject繼承的對象則會顯示名稱及行號。}
The block is currently used for an object of class: Unknown
{將記憶體塊頭256個字元顯示出現,作為內容提示。}
Current memory dump of 256 bytes starting at pointer address 107BDD8:
第二部分是總結性內容,例:
{這個小型記憶體塊泄漏的報告,如果有大型記憶體塊泄漏則會加一行專門提示大型記憶體塊泄漏。}This application has leaked memory. The small block leaks are (excluding expected leaks registered by pointer):
{21-28位元組的記憶體塊泄漏,未知類型一個}
21 - 28 bytes: Unknown x 1
Note: Memory leak detail is logged to a text file in the same folder as this application. To disable this memory leak check, undefine “EnableMemoryLeakReporting”.
有了這份報告只不過瞭解到記憶體流失存在,但是哪裡沒釋放就還需要更進一步地調查。
調查的目標有:
- 記憶體塊分配在哪個函數裡哪段代碼。
這個在報告裡可以結合內容和呼叫堆疊來看。前256個位元組可以進行分析,推測分配者,呼叫堆疊就直接指出了分配函數,不過是一些地址,不能直接知道函數名和程式碼片段。這時候就需要在delphi ide環境下查看二進位記憶體映像了,就是View CPU功能。在設定斷點並停下後,可以View CPU,在菜單View=>Debug Window=>CPU ,快速鍵:Ctrl+Alt+C,View CPU視窗正中就是記憶體映像,而且源碼也相應地標註好了,左邊列的地址就是記憶體報告中的Call Stack中的地址,翻頁找到所對應的代碼就知道哪裡分配記憶體了。
2.檢查釋放記憶體的地方是否被調用
可以用日誌或斷點來調試,如果壓根就沒有釋放記憶體那就補上代碼,如果有卻沒有執行則檢查一下執行條件是否正確,如果斷點沒起作用很可能是因為代碼永遠不會被執行(無作用程式碼)。這要靠經驗和調試,基本上藉助IDE和記憶體報告就可以很好地防止記憶體流失。同時要加強測試案例,爭取在測試案例中能遍曆到所有的代碼和大部分關鍵功能,這樣記憶體流失報告就會更準確一點。
fastmm每次在程式關閉後就會根據情況產生記憶體流失報告,如果沒有彈出記憶體流失警告則恭喜你,記憶體管得很好。
另外:
1).記憶體管理不是GC自動回收記憶體,而是檢查是否有泄漏。
2).windows系統的記憶體流失是無法檢查的,僅限於應用程式內部,不過檢查出系統泄漏也沒辦法,只能等更新了。
3).檢查泄漏後要自己去檢查代碼補齊記憶體釋放,報告並不能做這事
參考
http://www.cnblogs.com/rogge7/p/4601083.html
delphi fastmm4 調試