內存異常增長的檢測系統及方法與流程
2023-06-25 11:06:31 2
本發明涉及計算機系統技術領域,尤其涉及內存分配、管理和分析技術領域,具體是指一種內存異常增長的檢測系統及方法。
背景技術:
內存異常增長包含內存洩露和非洩露性質的內存異常增長,當前主流的內存檢測工具都偏向檢測內存洩露的情形,一般內存洩露檢測方法是,hook目標進程的內存管理函數,在目標進程生命周期結束的時候,若檢測到目標進程有未釋放的內存,則目標進程內存洩露。而對於無法結束其生命周期的進程,比較流行的一種檢測方法是基於時間片輪詢檢查目標進程在兩個時間點之間內存使用情況,進而找到內存洩露的懷疑點,然後再由程式設計師代碼分析判斷。但是,目前已知的工具,並沒有特別針對非洩露的內存增長檢測工具,而已知的內存檢測工具存在以下不足:
1、對於系統級別進程,其生命周期與系統同步,依賴進程生命周期結束的工具,無法檢測該類進程。
2、基於時間片檢測內存洩露的工具,其時間片就是個經驗值,無法應對任意場景的內存洩露,並且對於小內存洩露,無法準確偵測和排除噪點。
3、目前流行的工具都不能準確偵測非洩露性質的內存異常增長,比如短時間內申請大量內存,之後再釋放,該場景依然會可能導致系統異常,但卻事後從內存上無法發現問題,而且內存洩露工具也無法準確發現該異常。
技術實現要素:
本發明的目的是克服了上述現有技術的缺點,提供了一種能夠解決特殊情況下出現的內存非洩露性異常增長的情況和系統級生命周期的進程內存洩露的問題,並實現檢測內存異常增長的系統及方法。
為了實現上述目的,本發明具有如下構成:
該內存異常增長的檢測系統,包括:
內存記錄模塊,用於註冊鉤子函數並記錄所有已經申請的內存的元數據;
內存監控模塊,用於監控目標進程的已使用內存,並在出現內存異常增長且熬過閾值時記錄所述的內存記錄模塊所保存的元數據;
數據分析模塊,用於分析內存監控模塊的所有數據,將元數據轉換成調試信息並生成可視化信息,顯示內存異常增長的總大小和各個內存申請點所申請內存的大小和百分比。
還包括一種基於上述系統實現內存異常增長的檢測方法,所述的方法包括以下步驟:
(1)在進程啟動時通過所述的內存記錄模塊註冊鉤子函數;
(2)所述的內存記錄模塊對進程的內存申請和釋放過程進行記錄
(3)所述的內存監控模塊對內存的使用情況進行監控,並在出現內存異常增長且熬過閾值時記錄所述的內存記錄模塊所保存的元數據;
(4)所述的數據分析模塊分析並生成可視化數據和調試信息。
較佳地,所述的步驟(2)包括以下步驟:
(3-1)應用發起內存申請的請求;
(3-2)通過所述的鉤子函數記錄內存元數據並保存到哈希表;
(3-3)向系統申請內存;
(3-4)檢查內存佔用是否超過閾值,如果是,則繼續步驟(2-5),否則,完成本次內存申請的監控;
(3-5)通知內存監控模塊記錄當前進程的所有內存信息;
(3-6)更新當前進程的內存閾值。
更佳地,所述的更新當前進程的內存閾值,具體為:
基於最大佔用內存或最小佔用內存的穩步更新當前進程的內存閾值,或者基於最大佔用內存或最小佔用內存的梯度更新當前進程的內存閾值。
較佳地,所述的內存記錄模塊進程的內存釋放過程進行記錄並監控,具體包括以下步驟:
(3-7)進程申請內存釋放;
(3-8)鉤子函數檢查當前釋放的內存的元數據是否被記錄,如果是,則刪除元數據並繼續步驟(3-9),否則,繼續步驟(3-9);
(3-9)釋放進程的內存。
較佳地,所述的步驟(3)包括以下步驟:
(4-1)根據內存監控模塊獲取的數據,通過比較任意兩次內存申請的數據獲得內存增加的元數據表;
(4-2)合併所述的元數據表並生成對應的調試信息,對信息進行排序;
(4-3)根據所述的調試信息生成可視化圖標和調試信息表。
採用了該發明中的內存異常增長的檢測系統及方法,實現了內存異常增長的檢測和統計,基於鉤子函數並不改動內存申請邏輯,可以在進程運行同時自由啟動和關閉;可以檢測到任意短時間內的內存突發性增長,對於內存非洩露性質的異常增長的檢測效果顯著;對於生命周期長的進程的內存洩露,該方案能較準確定位洩露位置並提供可靠的調試數據;通過分析任意一次內存增長前後的內存信息,可以獲得內存增長點和圖表統計數據;通過比對多個圖表,在一定程度上排除噪點,增加判斷內存異常位置的準確性。
附圖說明
圖1為本發明的內存異常增長的檢測系統的示意圖。
圖2為本發明的內存異常增長的檢測系統的數據交互的示意圖。
圖3為本發明的內存異常增長的檢測方法的註冊鉤子函數的示意圖。
圖4為本發明的內存異常增長的檢測方法的內存申請的示意圖。
圖5為本發明的內存異常增長的檢測方法的內存釋放的示意圖。
具體實施方式
為了能夠更清楚地描述本發明的技術內容,下面結合具體實施例來進行進一步的描述。
為了解決特殊情況下出現的內存非洩露性異常增長的情況和系統級生命周期的進程內存洩露的問題,並實現檢測內存異常增長,本發明提出了一種內存異常增長的檢測系統,請參閱圖1所示,該系統包括三個模塊:
一、內存記錄模塊,用於記錄所有已經申請的內存的元數據信息,包括內存大小等。
1、基於鉤子函數原理,在系統內存申請和釋放的同時,記錄下相關元數據信息,所謂的鉤子函數,就是在正常的調用中插入一個函數或接口,而這個函數或接口可以繼續後續的正常調用,也可以預先處理數據,或者直接返回,本發明裡,鉤子函數實現是預先處理數據,之後繼續後續的正常調用。
二、內存監控模塊,用於監控目標進程的已使用內存,並在出現內存異常增長並增長達到閾值記錄下內存記錄模塊所保存的數據。
1、由於內存申請的鉤子函數並不改動內存申請邏輯,所以該監控模塊可以在進程運行時,隨時啟動和關閉。
2、基於內存增長閾值作為觸發條件,該方案可以檢測到任意短時間內的內存突發性增長,即使是在內存增長後立即釋放。所以,對於內存非洩露性質的異常增長的檢測,效果顯著。
3、基於內存增長閾值作為觸發條件,該方案可以檢測與系統生命周期等長的進程內存洩露情況。但是,為了避免第2點的情況帶來誤差,建議是在進程內存穩定後開啟檢測,內存增長閾值至少為1m,並且多次抓取內存變化的數據。所以,對於生命周期長的進程的內存洩露,該方案能較準確定位洩露位置並提供可靠的調試數據。
三、數據分析模塊,該模塊用於分析內存監控模塊所導出的所有數據,將所有之前抓取的元數據轉換成相應調試信息並生成可視化信息,顯示內存異常增長的總大小和各個內存申請點所申請內存的大小和百分比。
1、通過分析任意一次內存增長前後的內存信息,可以獲得內存增長點和圖表統計數據。
2、通過比對多個圖表,在一定程度上排除噪點,增加判斷內存異常位置的準確性。
在一種具體的實施方式中,該內存異常增長的檢測系統,包括:
內存記錄模塊,用於註冊鉤子函數並記錄所有已經申請的內存的元數據;
內存監控模塊,用於監控目標進程的已使用內存,並在出現內存異常增長且熬過閾值時記錄所述的內存記錄模塊所保存的元數據;
數據分析模塊,用於分析內存監控模塊的所有數據,將元數據轉換成調試信息並生成可視化信息,顯示內存異常增長的總大小和各個內存申請點所申請內存的大小和百分比。
以上三個模塊的信息交互關係和數據流請參閱圖2所示,這三個模塊在完整的控制流程中的運作方式如下所述:
一、進程啟動註冊鉤子函數,請參閱圖3所示:
11、進程啟動;
12、註冊鉤子函數。
二、內存監控模塊監控進程內存使用
21、內存申請,請參閱圖4所示:
211、應用申請內存,具體是指應用發起內存申請的請求,具體到代碼層面是調用內存分配函數;
212、鉤子函數記錄內存元數據並保存到哈希表,在該方案中使用哈希表的原因是快,內存申請必須要快,最好是在添加「鉤子函數」後,儘量不影響內存申請速度,否則可能會造成應用運行異常(比如時序改變,交互響應變慢等),所以,任何足夠快的數據結構或者算法,都可以替換掉哈希表的實現;
213、向系統申請內存,具體是指向底層的內存池(如果基礎庫實現了內存池功能)或者向內核申請內存(如果基礎庫未實現內存池功能),其中,基礎庫是指進程運行所必須的庫,比如libc等庫,在申請完內存後,進程就可以佔用和使用相應的內存;
214、檢查內存佔用是否達到閾值;
215、如果內存達到閾值,則通知內存監控模塊記錄當前進程內存所有信息,並更新內存閾值,本方案的功能是抓取應用內存的異常增長,而內存的漲跌是最不可預測的,應用可以在某個時間申請很大內存,用完立即釋放,更新內存閾值,就可以多次基於不同的閾值情況下抓取相應的數據,數據分析模塊可以基於這些數據分析出該單次內存的申請,也可以從統計的信息中,分析出該次內存被正常釋放了;更新閾值的方法涉及到具體的實現,可根據需求實現不同的方法,目前有的實現方法是:1、基於最大佔用內存(或最小佔用內存)的穩步更新,比如說,設定內存增長步長為1m,則每次閾值更新都是基於當前內存佔用的基礎上增加1m,該實現適用於開發人員了解該應用的內存增長情況;2、基於最大佔用內存(或最小佔用內存)的梯度更新,比如說,設定內存增長基礎步長為1m,則每次更新閾值在當前步長的基礎上增加一定的值,比如下次步長變成2m,再下次4m,該實現方法適用於開發人員不清楚應用的內存增長情況。
22、內存釋放,請參閱圖5所示:
221、鉤子函數檢查當前釋放內存是否被記錄;
222、如果記錄,則從哈希表中刪除相關數據,本方案的目的是檢測內存異常增長,而異常增長的原因就是只有內存申請,未有內存釋放,而數據分析模塊是要分析並生成所有只申請內存未釋放的數據並轉換成可視化信息,所以,在有內存釋放的時候,代表這塊被釋放的內存不屬於異常增長點,就要刪除相應的元數據記錄,避免被統計到最後的調試信息和可視化信息中;
223、釋放內存,即將內存返回給內存池或者是內核,需要注意的是釋放內存並不是關閉應用,而是應用發起的跟申請內存相對應的行為。
三、數據分析模塊分析並生成可視化數據和調試信息
31、基於內存監控模塊獲取的數據,任意兩次之間進行比較獲得內存增加的元數據表;
32、基於步驟31生成的表進一步合併和生成對應的調試信息,並基於內存增長的從大到小排序;
33、基於步驟32生成可視化圖標和調試信息表,用於開發人員的分析和快速定位。
在一種具體的實施方式中,本發明還包括一種基於上述系統實現內存異常增長的檢測方法,所述的方法包括以下步驟:
(1)在進程啟動時通過所述的內存記錄模塊註冊鉤子函數;
(2)所述的內存記錄模塊對進程的內存申請和釋放過程進行記錄
(3)所述的內存監控模塊對內存的使用情況進行監控,並在出現內存異常增長且熬過閾值時記錄所述的內存記錄模塊所保存的元數據;
(4)所述的數據分析模塊分析並生成可視化數據和調試信息。
在一種較佳的實施方式中,所述的步驟(2)包括以下步驟:
(3-1)應用發起內存申請的請求;
(3-2)通過所述的鉤子函數記錄內存元數據並保存到哈希表;
(3-3)向系統申請內存;
(3-4)檢查內存佔用是否超過閾值,如果是,則繼續步驟(2-5),否則,完成本次內存申請的監控;
(3-5)通知內存監控模塊記錄當前進程的所有內存信息;
(3-6)更新當前進程的內存閾值。
在一種更佳的實施方式中,所述的更新當前進程的內存閾值,具體為:
基於最大佔用內存或最小佔用內存的穩步更新當前進程的內存閾值,或者基於最大佔用內存或最小佔用內存的梯度更新當前進程的內存閾值。
在一種較佳的實施方式中,所述的內存記錄模塊進程的內存釋放過程進行記錄並監控,具體包括以下步驟:
(3-7)進程申請內存釋放;
(3-8)鉤子函數檢查當前釋放的內存的元數據是否被記錄,如果是,則刪除元數據並繼續步驟(3-9),否則,繼續步驟(3-9);
(3-9)釋放進程的內存。
在一種較佳的實施方式中,所述的步驟(3)包括以下步驟:
(4-1)根據內存監控模塊獲取的數據,通過比較任意兩次內存申請的數據獲得內存增加的元數據表;
(4-2)合併所述的元數據表並生成對應的調試信息,對信息進行排序;
(4-3)根據所述的調試信息生成可視化圖標和調試信息表。
在具體實現中,鉤子函數的內容就是內存記錄模塊,內存元數據的核心內容有:內存申請調用的堆棧信息和當前申請的內存大小,鉤子函數將該這些信息獲取,以堆棧和請求的內存大小為依據在哈希表中查找,若對象已存在,則增加內存申請的次數,以表示該堆棧該大小的內存再次被申請了,而哈希表屬於全局變量,可以被內存記錄模塊和內存監控模塊共同所訪問。
採用了該發明中的內存異常增長的檢測系統及方法,實現了內存異常增長的檢測和統計,基於鉤子函數並不改動內存申請邏輯,可以在進程運行同時自由啟動和關閉;可以檢測到任意短時間內的內存突發性增長,對於內存非洩露性質的異常增長的檢測效果顯著;對於生命周期長的進程的內存洩露,該方案能較準確定位洩露位置並提供可靠的調試數據;通過分析任意一次內存增長前後的內存信息,可以獲得內存增長點和圖表統計數據;通過比對多個圖表,在一定程度上排除噪點,增加判斷內存異常位置的準確性。
在此說明書中,本發明已參照其特定的實施例作了描述。但是,很顯然仍可以作出各種修改和變換而不背離本發明的精神和範圍。因此,說明書和附圖應被認為是說明性的而非限制性的。