陳 楠
(中國石油化工股份有限公司 石油物探技術(shù)研究院, 南京 211103)
基于C++的動態(tài)內(nèi)存實時監(jiān)測器①
陳 楠
(中國石油化工股份有限公司 石油物探技術(shù)研究院, 南京 211103)
通過對地球物理軟件研發(fā)過程中比較常見內(nèi)存錯誤的調(diào)研與總結(jié), 設(shè)計并實現(xiàn)了一個基于C/C++的動態(tài)內(nèi)存檢測工具, 采用內(nèi)嵌與關(guān)鍵函數(shù)截獲方式, 對編譯器開放接口進行擴展與改進. 該工具通過對軟件運行過程中堆內(nèi)存使用情況的實時收集、分類統(tǒng)計與分析, 達到動態(tài)的監(jiān)控與檢測內(nèi)存堆棧錯誤的目的. 以中國石化石油物探技術(shù)研究院自主研發(fā)的油氣綜合解釋系統(tǒng)NEWS子系統(tǒng)-疊前疊后聯(lián)合解釋模塊主要流程為例, 用該檢測工具對其進行全面的測試與應(yīng)用. 實踐表明, 嵌入監(jiān)測器的應(yīng)用軟件在開發(fā)過程中大幅降低了內(nèi)存泄漏現(xiàn)象, 運行時減少了內(nèi)存錯誤導致的異常崩潰現(xiàn)象, 提高了應(yīng)用軟件的穩(wěn)定性, 并能夠?qū)﹂_發(fā)以及測試人員快速定位與分析軟件錯誤起到較強的指導作用.
內(nèi)存泄漏; 重載; 檢測; 調(diào)用棧; NEWS
隨著野外油氣勘探技術(shù)的發(fā)展與進步, 采集數(shù)據(jù)信息量的增多也使得地震數(shù)據(jù)變得日趨龐大, 大數(shù)據(jù)量任務(wù)處理一直是地球物理軟件研發(fā)人員不斷研究與探索的技術(shù)課題, 計算機物理內(nèi)存的管理也越來越復雜[1], 操作系統(tǒng)從32位升級到64位, 理論上將64位CPU的尋址空間從4GB擴展到了無窮大(遠遠超出物理內(nèi)存大小), 解決了程序設(shè)計中物理內(nèi)存分配的上限問題, 不過這樣往往導致了另外一個問題: 程序員們對手動釋放物理內(nèi)存的意識逐漸變得淡薄, 以至于在系統(tǒng)性能變得低下甚至頻臨崩潰時才意識到問題嚴重,但此時的開發(fā)規(guī)模也使得排查工作變得復雜無序, 筆者雖具備多年一線軟件研發(fā)經(jīng)驗, 但當出現(xiàn)內(nèi)存問題累積引發(fā)的系統(tǒng)性能問題方面, 也感到維護工作非常困難, 輕者按程序流程分支逐一排查測試, 重則推倒重來, 新手遇到類似問題更是感到無從下手, 往往嚴重影響項目研發(fā)進度. 針對這些現(xiàn)象, 第三方解決方案其實已經(jīng)存在, Windows系統(tǒng)下有MFC內(nèi)嵌的內(nèi)存監(jiān)測工具可以實時跟蹤應(yīng)用軟件內(nèi)存情況并提示定位內(nèi)存泄漏信息[2,3], 但該工具不支持MingW編譯器, Linux系統(tǒng)下相對來說就沒有那么容易使用的解決方案, 而mpatrol之類的現(xiàn)有工具, 在易用性、附加開銷和性能等方面都不是很理想[4-6].
一個成熟的軟件產(chǎn)品往往都已經(jīng)對外發(fā)布試用與銷售, 隨著應(yīng)用范圍的擴大, 不可避免地也會存在一定數(shù)量的bug, 如果不具備遠程調(diào)試的條件, 開發(fā)人員僅僅從用戶的反饋信息中很難準確定位軟件在使用過程中出現(xiàn)的問題.
綜上所述, 在軟件工程開發(fā)的過程中, 一個具備全程動態(tài)跟蹤功能的、跨平臺的錯誤定位與內(nèi)存檢測工具是很有必要的.
一般情況下, 實時檢測程序應(yīng)該具備以下幾個基本功能: ①全程跟蹤并記錄程序中內(nèi)存分配和釋放情況[7]; ②監(jiān)控分配的內(nèi)存是否為有效數(shù)據(jù); ③在發(fā)生異常崩潰時進行跳轉(zhuǎn)處理并回溯崩潰點的函數(shù)調(diào)用棧, 提示開發(fā)人員定位崩潰點位置找出錯誤; ④支持線程安全.
3.1 程序調(diào)用棧(call stack)原理分析
功能: 主要用于程序異常退出時尋找錯誤點, 回溯堆棧, 列出當前錯誤序列函數(shù)的調(diào)用關(guān)系.
原理: 通過對當前堆棧的分析, 找到其上層函數(shù)在棧中的幀地址, 再分析上層函數(shù)的堆棧, 再找再上層的幀地址, 一直找到最頂層為止, 幀地址指的是一塊在棧上存放局部變量, 上層返回地址, 及寄存器值的空間.
要了解調(diào)用棧, 首先需要了解函數(shù)的調(diào)用過程,下面用一段簡單代碼作為例子:
通過對代碼的反匯編可以看到(圖1), 進入add函數(shù)后, 首先進行的操作是將當前的棧基址ebp壓棧(此?;肥钦{(diào)用者main函數(shù)的), 然后將ebp指向棧頂esp, 接下來再進行函數(shù)內(nèi)的處理流程. 函數(shù)結(jié)束前,會將函數(shù)調(diào)用者的棧基址恢復, 然后返回準備執(zhí)行下一指令. 這個過程中, 棧上的空間展布如圖2 所示.
圖1 反匯編代碼解析
可以發(fā)現(xiàn), 每調(diào)用一次函數(shù), 都會對調(diào)用者的?;?ebp)進行壓棧操作(圖2), 并且由于?;肥怯僧敃r棧頂指針(esp)而來, 會發(fā)現(xiàn), 各層函數(shù)的?;泛芮擅畹臉?gòu)成了一個鏈, 即當前的棧基址指向下一層函數(shù)?;匪诘奈恢? 如圖2所示.
圖2 調(diào)用棧關(guān)系
了解函數(shù)的調(diào)用過程, 想要回溯調(diào)用棧也就容易了, 首先獲取當前函數(shù)的棧基址(寄存器ebp)的值, 然后獲取該地址所指向的棧的值, 該值也就是下層函數(shù)的?;? 找到下層函數(shù)的?;泛? 重復剛才的動作, 即可以將每一層函數(shù)的?;范颊页鰜? 這也就是我們所需要的調(diào)用棧了,前面描述的是函數(shù)棧的內(nèi)存結(jié)構(gòu)關(guān)系和調(diào)用邏輯, 在不同編譯器條件下可能會出現(xiàn)內(nèi)存高低位置的互換, 但并不影響對棧結(jié)構(gòu)的分析和研究[8,9].
3.2 動態(tài)內(nèi)存泄漏檢測
功能: 實時監(jiān)控內(nèi)存分配與釋放情況.
原理: 重載與替換系統(tǒng)內(nèi)存分配釋放函數(shù).
棧內(nèi)存在函數(shù)結(jié)束時由系統(tǒng)自動回收釋放, 所以不會造成泄漏現(xiàn)象, 一般我們常說的內(nèi)存泄漏是指堆內(nèi)存的分配與釋放不匹配導致[10-12]. 堆內(nèi)存是程序從堆中分配的, 大小任意的(理論上內(nèi)存塊的大小可以在程序運行期決定), 使用完后必須顯示釋放的內(nèi)存. 應(yīng)用程序一般使用malloc, realloc, new等函數(shù)從堆中分配到一塊內(nèi)存, 使用后, C++程序員必須手動調(diào)用相應(yīng)的free或delete釋放該內(nèi)存塊, 否則, 這塊內(nèi)存就不能被系統(tǒng)回收再次使用, 從而造成泄漏. 內(nèi)存泄漏不僅僅包含堆內(nèi)存的泄漏, 還可以包含系統(tǒng)資源的泄漏(resource leak), 比如核心態(tài)指針如HANDLE, GDI Object, SOCKET, Interface等, 從根本上說這些由操作系統(tǒng)分配的對象也消耗內(nèi)存, 如果這些對象發(fā)生泄漏最終也會導致物理內(nèi)存的丟失. 而且, 某些對象消耗的是核心態(tài)內(nèi)存, 這些對象嚴重泄漏時會導致整個操作系統(tǒng)不穩(wěn)定. 所以相比之下, 系統(tǒng)資源的泄漏比堆內(nèi)存的泄漏更為嚴重[13]. 以發(fā)生的方式來分類, 內(nèi)存泄漏可以分為4類:
① 常發(fā)性內(nèi)存泄漏. 發(fā)生內(nèi)存泄漏的代碼會被多次執(zhí)行到, 每次被執(zhí)行的時候都會導致一塊內(nèi)存泄漏, 這種泄漏在地球物理軟件批量處理模塊中比較常見.
② 偶發(fā)性內(nèi)存泄漏. 發(fā)生內(nèi)存泄漏的代碼只有在某些特定環(huán)境或操作過程下才會發(fā)生, 比如在某分支條件下的用戶交互操作. 對于特定的環(huán)境, 偶發(fā)性的也許就變成了常發(fā)性的. 所以測試環(huán)境和測試方法對檢測內(nèi)存泄漏也是至關(guān)重要.
③ 一次性內(nèi)存泄漏. 發(fā)生內(nèi)存泄漏的代碼只會被執(zhí)行一次, 或者由于算法上的缺陷, 導致總會有一塊僅且一塊內(nèi)存發(fā)生泄漏. 比如, 在類的構(gòu)造函數(shù)中分配內(nèi)存, 在析構(gòu)函數(shù)中卻沒有釋放該內(nèi)存, 所以內(nèi)存泄漏只會發(fā)生一次, 或者是一些全局靜態(tài)指針等等.
④ 隱式內(nèi)存泄漏. 程序在運行過程中不停的分配內(nèi)存, 但是直到結(jié)束的時候才釋放內(nèi)存. 嚴格的說這里并沒有發(fā)生內(nèi)存泄漏, 因為最終程序釋放了所有申請的內(nèi)存. 但是對于一個服務(wù)器程序, 需要運行幾天, 幾周甚至幾個月, 不及時釋放內(nèi)存也可能導致最終耗盡系統(tǒng)的所有內(nèi)存. 所以, 我們稱這類內(nèi)存泄漏為隱式內(nèi)存泄漏, 作為一般的用戶, 通常感覺不到內(nèi)存泄漏的存在. 真正有危害的是內(nèi)存泄漏的堆積[14],這會最終消耗盡系統(tǒng)所有的內(nèi)存. 從這個角度來說,一次性內(nèi)存泄漏并沒有什么危害, 因為它不會堆積,而隱式內(nèi)存泄漏危害性則較大, 因為它更難被檢測到,所以這方面的問題需要從軟件程序的優(yōu)化方面考慮解決.
檢測內(nèi)存泄漏的關(guān)鍵是要能截獲住對分配內(nèi)存和釋放內(nèi)存的函數(shù)的調(diào)用[15]. 截獲住這兩個函數(shù), 我們就能跟蹤每一塊內(nèi)存的生命周期, 比如, 每當成功的分配一塊內(nèi)存后, 就把它的指針加入一個全局的list中; 每當釋放一塊內(nèi)存, 再把它的指針從list中刪除.這樣, 當程序結(jié)束的時候, list中剩余的指針就是指向那些沒有被釋放的內(nèi)存. 這里只是簡單的描述了檢測內(nèi)存泄漏的基本原理[16], 文章后面再詳述討論. 在new/delete操作中, C++為開發(fā)人員產(chǎn)生了對operator new和operator delete的調(diào)用. 這是不能改變的. 對于"new int", 編譯器會產(chǎn)生一個調(diào)用"operator new(sizeof(int))", 而對于"new char[10]", 編譯器會產(chǎn)生"operator new[](sizeof(char) * 10)"(如果new后面跟的是一個類名的話, 編譯器還要調(diào)用該類的構(gòu)造函數(shù)).類似地, 對于"delete ptr"和"delete[] ptr", 編譯器會產(chǎn)生"operator delete(ptr)"調(diào)用和"operator delete[](ptr)"調(diào)用(如果ptr的類型是指向?qū)ο蟮闹羔樀脑? 那在operator delete之前還要調(diào)用對象的析構(gòu)函數(shù)). 當用戶沒有提供這些操作符時, 編譯系統(tǒng)自動提供其定義;而當用戶自己提供了這些操作符時, 就覆蓋了編譯器提供的函數(shù)版本, 從而找到了可獲得對動態(tài)內(nèi)存分配操作的精確跟蹤和控制的入口. 基于此, 利用自定義宏在用戶程序中進行替換, 重載操作符operator new,格式如下所示.
void* operator new(size_t nsize, const char* cfile,
其他內(nèi)存分配操作符如表1所示, 重載后的operator new可以跟蹤覆蓋應(yīng)用程序內(nèi)部所有的內(nèi)存分配調(diào)用, 并在指定的檢查點上對不匹配的new和delete操作進行自定義處理.
表1 其他內(nèi)存分配操作符
3.3 功能擴展
3.3.1 監(jiān)測記錄
通過重載系統(tǒng)內(nèi)存操作符,用戶接替了編譯器對物理內(nèi)存分配的管理,靈活度大幅提高, 此時可以嵌入必要的記錄機制[15,16], 達到用戶對應(yīng)用程序內(nèi)存使用情況的全面監(jiān)測. 比較常用的方法是記錄分配內(nèi)存的指針地址[17-20], 這樣消耗的內(nèi)存空間比較小, 檢索的速度也比較快, 為了提高檢索效率, 可以定義STL的散列表對象, 把申請內(nèi)存的文件名、行號、對象大小信息分別存入file、line和size字段中, 然后返回(malloc返回的指針 + sizeof(new_ptr_list_t)). 在delete時, 則在散列表中搜索, 如果找到的話((char*)鏈表指針 + sizeof(new_ptr_list_t) == 待釋放的指針), 則調(diào)整鏈表、釋放內(nèi)存, 找不到的話報告刪除非法指針并abort, 過程如圖3所示. 要得到精確的內(nèi)存泄漏檢測報告, 可以在文件開頭包含"debug_new.h". 包含的位置應(yīng)當盡可能早, 除非跟系統(tǒng)的頭文件(典型情況是STL的頭文件)發(fā)生了沖突. 在某些情況下, 可能會不希望debug_new重定義new, 這時可以在包含debug_new.h之前定義DEBUG_NEW_NO_NEW_ REDEFINITION, 這樣的話, 在用戶應(yīng)用程序中應(yīng)使用debug_new來代替new(順便提一句, 沒有定義DEBUG_NEW_NO_NEW_REDEFINITION時也可以使用debug_new代替new). 在源文件中也許就該這樣寫:
并在需要追蹤內(nèi)存分配的時候全部使用debug_new(考慮使用全局替換). 用戶可以選擇定義DEBUG_NEW_EMULATE_MALLOC, 這樣debug_new.h會使用debug_new和delete來模擬malloc和free操作, 使得用戶程序中的malloc和free操作也可以被跟蹤, 反之也可以選擇性的宏定義啟動開關(guān),在發(fā)布版本中用戶可以關(guān)閉跟蹤功能, 避免實際應(yīng)用中效率的降低.
圖3 監(jiān)測記錄流程圖
3.3.2 多線程支持
線程是否可重入是編寫監(jiān)測器API函數(shù)必須考慮的情況, 線程安全問題都是由全局變量及靜態(tài)變量引起的, 內(nèi)存監(jiān)測器本身就是一個全局控制器[21-23], 內(nèi)部有比較頻繁的I/O操作, 所以要加入讀寫互斥鎖用以保證線程安全性[24,25], 加入互斥鎖機制后的監(jiān)控器才能提供多線程支持, 這也是通用性設(shè)計的一個方面.
中石化物探院NEWS軟件子系統(tǒng)-“疊前疊后聯(lián)合解釋軟件”是一套集實時疊前分析、偏移距/入射角部分疊加、AVO屬性分析及P波疊前裂縫檢測等功能為一體的綜合性疊前數(shù)據(jù)解釋工具, 軟件工程方面也是具備了實時聯(lián)動分析、交互圖形顯示和批量處理功能等綜合特征. 前期研發(fā)過程中較側(cè)重于模塊功能效果開發(fā), 導致了該系統(tǒng)自1.0版本起就有輕微的內(nèi)存泄漏與越界現(xiàn)象, 但并不明顯, 不影響研究使用, 隨著功能的擴充和應(yīng)用范圍的加大, 在經(jīng)過反復的交互使用與圖形顯示輸出后, 出現(xiàn)了內(nèi)存使用明顯增多的現(xiàn)象, 從程序啟動時的80M, 經(jīng)過約168小時的方位各向異性批量處理運算后可以飆升到800 M左右, 運行該模塊的機器性能明顯下降.
由于工程代碼量大, 程序復雜, 用傳統(tǒng)的手工逐一排查方式工作量和風險性都很大, 開發(fā)團隊隨即在系統(tǒng)中嵌入了動態(tài)內(nèi)存檢測工具, 進行了全覆蓋的排查, 原因分析與修正: 1、交互過程中有零散的內(nèi)存泄漏現(xiàn)象, 通過檢測器記錄的泄漏位置逐一修正釋放. 2、檢測器記錄顯示, 在進行單機多線程并行計算時,程序定義的n個線程并發(fā)進行內(nèi)存分配, 并將指針傳遞給一個數(shù)據(jù)存儲容器, 由m個線程從數(shù)據(jù)存儲進行數(shù)據(jù)處理和內(nèi)存釋放. 由于 n 遠大于m, 或者m個線程數(shù)據(jù)處理的時間過長, 導致內(nèi)存分配的速度遠大于內(nèi)存被釋放的速度. 這種問題在系統(tǒng)中較難發(fā)現(xiàn), 程序可能運行一段時間沒有問題, 從而通過了不嚴密的系統(tǒng)測試. 但是如果測網(wǎng)范圍大, 計算時間長的情況下, 系統(tǒng)將不定時的崩潰, 而且崩潰的原因從程序表象上都比較難檢測. 為了解決這種問題, 我們在檢測器內(nèi)部增加了一個動態(tài)檢測模塊, 同時啟動一個分析線程, 每隔一定的時間間隔就計算一下當前的以分配而尚未釋放的內(nèi)存信息, 并以內(nèi)存的分配位置為關(guān)鍵字進行統(tǒng)計, 查看在同一位置(相同文件名和行號)所分配的內(nèi)存總量和其占進程總內(nèi)存量的百分比. 這樣在程序運行過程中, 用戶能夠?qū)Τ绦虻膭討B(tài)內(nèi)存分配狀況進行監(jiān)視. 當客戶監(jiān)視一個運行中的進程時, 被監(jiān)視進程的內(nèi)存子系統(tǒng)將把內(nèi)存分配和釋放的信息實時傳送給檢測器. 檢測器則每隔一定的時間間隔就對所接收到的信息進行統(tǒng)計, 計算該進程總的內(nèi)存使用量, 同時以調(diào)用new或者malloc進行內(nèi)存分配的文件名和行號為索引值, 計算每個內(nèi)存分配動作所分配而未釋放的內(nèi)存總量. 用這種方法, 如果在連續(xù)多個時間間隔的統(tǒng)計結(jié)果中, 某文件的某行所分配的內(nèi)存總量不斷增長而始終沒有到達一個平衡點甚至回落, 說明該位置的內(nèi)存分配方式需要調(diào)整了. 當?shù)玫給perator new 的信息時, 記錄內(nèi)存分配信息, 當收到operator delete 消息時, 刪除相應(yīng)的內(nèi)存分配信息.
借助內(nèi)嵌的call stack調(diào)用棧回溯機制, 測試過程中出現(xiàn)的程序異常崩潰, 可以快速準確的定位到出錯文件與行號(如圖4及圖5所示), 使得糾錯效率大幅度的提高, 修正后的“疊前疊后聯(lián)合解釋軟件”在實際生產(chǎn)應(yīng)用中運行穩(wěn)定, 計算速度也得到明顯提升.
圖4 異常函數(shù)示例
圖5 異常錯誤定位
圖6 內(nèi)存泄漏監(jiān)控記錄
開發(fā)了一套跨平臺的基于C/C++的動態(tài)內(nèi)存檢測工具, 集成了函數(shù)調(diào)用?;厮?、實時內(nèi)存分配監(jiān)測、內(nèi)存使用與釋放回饋等技術(shù), 以圖形或者文本的方式向開發(fā)用戶提交檢測預警記錄(如圖6所示), 在實際項目的使用中具備以下幾個特征:
① 大型軟件開發(fā)過程明顯減少調(diào)試時間;
② 支持多平臺和跨平臺開發(fā);
③ 降低維護和支持成本;
④ 實時排除算法錯誤;
⑤ 減少軟件缺陷提高產(chǎn)品信譽;
⑥ 能夠與項目產(chǎn)品的開發(fā)生命周期無縫集成.
1 陳楠,祝媛媛,張光德,徐鈺.基于QT的地震勘探可擴展平臺研發(fā)與應(yīng)用.華北地震科學,2013,4:1003–1375.
2 周宇.基于調(diào)用棧完整性的緩沖區(qū)溢出檢測方法.計算機安全,2010,(3):16–19.
3 管曉宏,馮力,孫杰,等.Linux環(huán)境下基于調(diào)用棧圖的入侵檢測方法: CN,CN 1710866 A. 2005.
4 吳多多,楊偉偉,肖力濤.利用堆棧模擬C語言中函數(shù)的調(diào)用過程.科技信息,2011,(15).
5 楊禮波,張志亮.在堆棧緩沖區(qū)溢出中程序調(diào)用的分析和研究.電腦知識與技術(shù),2010,6(17):4686–4689.
6 徐建國.網(wǎng)絡(luò)化制造系統(tǒng)中虛擬加工若干關(guān)鍵技術(shù)研究[博士學位論文].南京:南京理工大學,2007.
7 肖謙,李中升,漆鋒濱.Linux下函數(shù)棧大小的自動計算技術(shù).計算機工程,2011,(S1).
8 梁玉,傅建明,彭國軍,等.S-Tracker: 基于棧異常的 shellcode檢測方法.華中科技大學學報(自然科學版),2014,(11): 39–46.
9 楊東.ARM嵌入式系統(tǒng)異常調(diào)試的研究和實現(xiàn)[碩士學位論文].上海:上海交通大學,2009.
10 戚曉芳,周曉宇,徐曉晶,等.一種組合式基于調(diào)用棧的程序切片方法.東南大學學報(自然科學版),2011,41(6):1171–1176.
11 周國亮,朱永利,王桂蘭,等.實時大數(shù)據(jù)處理技術(shù)在狀態(tài)監(jiān)測領(lǐng)域中的應(yīng)用.第六屆電工技術(shù)前沿問題學術(shù)論壇. 2014.
12 王呈祥.基于共享內(nèi)存的通用OLE Process Control3.0服務(wù)器的研究與設(shè)計[碩士學位論文].長春:吉林大學,2013.
13 劉黎志,劉君.空氣質(zhì)量實時監(jiān)測系統(tǒng)的內(nèi)存泄漏.武漢工程大學學報,2012,34(6):74–78.
14 周游弋.集群監(jiān)控系統(tǒng)中內(nèi)存數(shù)據(jù)庫的設(shè)計與應(yīng)用研究[碩士學位論文].上海:復旦大學,2010.
15 張飛.實時嵌入式操作系統(tǒng)動態(tài)內(nèi)存管理研究[學位論文].合肥:中國科學技術(shù)大學,2008.
16 李明.多核路由器動態(tài)內(nèi)存分配器的設(shè)計與實現(xiàn)[碩士學位論文].南京:南京理工大學, 2011.
17 劉曉偉.基于Linux的電力系統(tǒng)實時監(jiān)測系統(tǒng)的開發(fā)[碩士學位論文].武漢:華中科技大學,2006.
18 何波玲,張志春.內(nèi)存信息自動監(jiān)控器的設(shè)計與實現(xiàn).信息安全與技術(shù),2015,(6).
19 姚志強.一個實用的自釋放內(nèi)存TSR程序的設(shè)計要素.福建師范大學學報(自然科學版),1997,(2):27–32.
20 吳民,涂奉生.Linux下面向函數(shù)的動態(tài)內(nèi)存泄漏監(jiān)測.計算機工程與應(yīng)用,2003,39(6):37–40.
21 孝瑞.內(nèi)存動態(tài)安全監(jiān)測及防范研究[碩士學位論文].保定:華北電力大學,2015.
22 王文陵.內(nèi)存泄漏的處理與監(jiān)測.福建信息技術(shù)教育, 2005(3).
23 楊麗,郭祥昊.C語言常見內(nèi)存管理錯誤及內(nèi)存監(jiān)控功能的實現(xiàn).新浪潮,1996,(8):21–22.
24 陳鴻杰.物聯(lián)網(wǎng)在煤礦安全生產(chǎn)應(yīng)用中監(jiān)測與控制技術(shù)研究[碩士學位論文].西安:西安電子科技大學,2014.
25 寇雅楠,李增智,王建國,等.計算機軟件測試研究.計算機工程與應(yīng)用,2002,38(10):103–105.
Real-Time Monitor of Dynamic Memory Based on C++
CHEN Nan
(Sinopec Geophysical Research Institute, Nanjing 211103, China)
Through the summary of the common memory errors research in the geophysical software development process, we design and implement a dynamic memory detection tool based on C/C++ by using the embedded and key function interception, which can expand and improve the compiler open interface. Through the real-time collection, classification, statistic and analysis of the heap memory usage in the running process of software, the tool achieves dynamic monitoring and detection of false memory stack. We take the NEWS software subsystem of prestack and poststack joint interpretation module process as an example to test and apply it comprehensively. The practice shows that the monitor, embedded in the software, can greatly reduce the memory leak phenomenon during the development process, and decrease the runtime memory errors caused by abnormal collapse phenomenon, and improve the stability of the application software. It also plays a strong role in the development to help tester’s in rapid location and analysis of software errors.
memory leaks; overload; detection; call stack; NEWS
國家科技重大專項(2011ZX05035)
2016-03-14;收到修改稿時間:2016-04-19
10.15888/j.cnki.csa.005459