在Linux平臺上有valgrind能夠很是方便的幫助咱們定位內存泄漏,由於Linux在開發領域的使用場景大可能是跑服務器,再加上它的開源屬性,相對而言,處理問題容易造成「統一」的標準。而在Windows平臺,服務器和客戶端開發人員慣用的調試方法有很大不一樣。下面結合個人實際經驗,整理下常見定位內存泄漏的方法。api
注意:咱們的分析前提是Release版本,由於在Debug環境下,經過VLD這個庫或者CRT庫自己的內存泄漏檢測函數可以分析出內存泄漏,相對而言比較簡單。而服務器有不少問題須要在線上併發壓力狀況下才出現,所以討論Debug版調試方法意義不大。服務器
方法:在對象構造時計數++,析構時--,每隔一段時間打印對象的數量多線程
優勢:沒有性能開銷,幾乎不佔用額外內存。定位結果精確。併發
缺點:侵入式方法,需修改現有代碼,並且對於第三方庫、STL容器、腳本泄漏等因沒法修改代碼而沒法定位。函數
方法:重載new/delete,記錄分配點(甚至是調用堆棧),按期打印。工具
優勢:沒有看出性能
缺點:侵入式方法,需將頭文件加入到大量源文件的頭部,以確保重載的宏可以覆蓋全部的new/delete。記錄分配點須要加鎖(若是你的程序是多線程),並且記錄分配要佔用大量內存(也是佔用的程序內存)。測試
方法:使用微軟的detours庫,hook分配內存的系統Api:HeapAlloc/HeapRealloc/HeapFree(new/malloc的底層調用),記錄分配點,按期打印。
google
優勢:非侵入式方法,無需修改現有文件(hook api後,分配和釋放走到本身的鉤子函數中),檢查全面,對第三方庫、腳本庫等等都能統計到。spa
缺點:記錄內存須要佔用大量內存,並且多線程環境須要加鎖。
微軟出品的內存泄漏分析工具,原理同hookapi方式。配合LDGraph可視化展現內存分配數據,更方便查找泄漏。
在IDE工程選項裏面配置Release版本也生成調試信息,發佈時,將pdb文件和exe文件一塊兒發佈。
程序運行後,打開LeakDiag,設置Symbol path
按期Log下目標進程的內存分配狀況,經過LDGraph打印分配增加狀況,來發現內存泄漏。
優勢:同hookapi方法,非侵入式修改,無需作任何代碼改動。跟蹤全面。可視化分析堆棧盡收眼底!
缺點:對性能有影響,hook分配加鎖,遍歷堆棧。可是不會佔用目標進程的自身內存。
對於線上生產環境,建議大對象用計數來判斷,定位快速準確,幾乎無性能開銷。在對外測試階段,使用LeakDiag輔助分析,由於此時併發壓力還不是太大,性能開銷仍是能夠承受。在線上大規模應用階段,經過HookApi的方法,結合GM指令控制部分時間段的檢測,這樣能夠把對玩家的影響(服務器性能降低致使延遲)降到最低。
以上方法,我將後續的博客中逐一詳細介紹,文中提到到detours庫和LeakDiag工具,想了解的朋友,能夠上codeprojet上搜索下相關介紹,若是要上google查找資料,也能夠上這裏。若是你們有新方法也可留言討論,咱們共同完善這一系列的介紹文章。