檢測內存泄漏的方法和裝置的制造方法
【專利摘要】本發明實施例公開了一種檢測內存泄漏的方法和裝置。本發明實施例方法包括:創建第一數據結構;獲取預置對象的內存地址,將所述預置對象的存儲地址和堆棧信息存儲到所述第一數據結構中;獲取指針變量集合,所述指針變量集合包括內存空間中的所有指針變量;檢測所述第一數據結構中是否存在不被所述指針變量集合中的任一指針變量指向的內存地址;若存在,則確定內存泄漏,并確定所述內存地址中的對象為泄漏對象。
【專利說明】
檢測內存泄漏的方法和裝置
技術領域
[0001]本發明涉及計算機領域,特別是一種檢測內存泄漏的方法和裝置。
【背景技術】
[0002]內存泄漏,也稱作“存儲滲漏”,指的是用動態存儲分配函數動態開辟的空間在使用完畢后未釋放,導致對象一直占據該內存單元的現象。
[0003]現有的1s系統中采用leak內存泄漏檢測工具來檢測手機中的內存泄漏,但蘋果公司并沒有對外開放該工具的原理,該工具是一個在mac電腦上的軟件,因此每一次手機檢測內存泄漏時,都需要將手機連接到電腦才可以使用。這導致手機APP無法獨立檢測內存泄漏。
【發明內容】
[0004]本發明實施例提供了一種檢測內存泄漏的方法和裝置,能夠不依靠外界設備獨立檢測內存泄漏。
[0005]第一發明,本發明實施例提供一種檢測內存泄漏的方法,包括:
[0006]創建第一數據結構;
[0007]獲取預置對象的內存地址,將所述預置對象的存儲地址和堆棧信息存儲到所述第一數據結構中;
[0008]獲取指針變量集合,所述指針變量集合包括內存空間中的所有指針變量;
[0009]檢測所述第一數據結構中是否存在不被所述指針變量集合中的任一指針變量指向的內存地址;
[0010]若存在,則確定內存泄漏,并確定所述內存地址中的對象為泄漏對象。
[0011]第二方面,本發明實施例提供一種檢測內存泄漏的裝置,包括:
[0012]創建模塊,用于創建第一數據結構;
[0013]第一獲取模塊,用于獲取預置對象的內存地址,將所述預置對象的存儲地址和堆棧信息存儲到所述第一數據結構中;
[0014]第二獲取模塊,用于獲取指針變量集合,所述指針變量集合包括內存空間中的所有指針變量;
[0015]檢測模塊,用于檢測所述第一數據結構中是否存在不被所述指針變量集合中的任一指針變量指向的內存地址;
[0016]確定模塊,用于當所述第一數據結構中存在不被所述指針變量集合中的任一指針變量指向的內存地址時,確定內存泄漏,并確定所述內存地址中的對象為泄漏對象。
[0017]從以上技術方案可以看出,本發明實施例具有以下優點:
[0018]本發明實施例中,記錄對象的內存地址,并創建第一數據結構來存儲這些信息,通過分析所有包含指針變量的內存區域中的指針變量,對于沒有指針變量指向的對象,可認為在進程空間中無引用的對象,因此,當第一數據結構中存在沒有指針變量指向的對象時,確定該對象為泄漏對象,這樣,通過本發明中的檢測內存泄漏方法移動終端可以獨立檢測內存泄漏而無需依賴其他工具。
【附圖說明】
[0019]圖1為本發明的檢測內存泄漏的方法的一個實施例的流程示意圖;
[0020]圖2為本發明的檢測內存泄漏的方法中的獲取指針變量集合的方法的一種實施例的流程示意圖;
[0021]圖3為本發明的檢測內存泄漏的方法中的獲取指針變量集合的方法的另一種實施例的流程示意圖;
[0022]圖4為本發明的檢測內存泄漏的方法中的確認泄漏對象的方法的一種實施例的流程不意圖;
[0023]圖5為本發明的檢測內存泄漏的裝置的一個實施例的結構示意圖;
[0024]圖6為本發明的檢測內存泄漏的裝置的另一個實施例的結構示意圖。
【具體實施方式】
[0025]請參閱圖1,圖1為本發明的檢測內存泄漏的方法的一個實施例的流程示意圖。本實施例中,檢測內存泄漏的方法,包括:
[0026]101、創建第一數據結構。
[0027]本實施例中,第一數據結構用于存儲步驟102中所獲取的預置對象的內存地址。例如,該第一數據接口為哈希表、紅黑樹或者鏈表,在此不作限制。優選的,該第一數據結構為哈希表,相比其他數據結構,哈希表的效率較高。
[0028]102、獲取預置對象的內存地址,將所述預置內存對象的內存地址和堆棧信息存儲到所述第一數據結構中。
[0029]本實施例中,預置對象為已經分配了內存地址且為需要監控的對象。例如,該預置對象為所有內存區中分配好內存地址的對象。或者,該預置內存對象為objective-c類對象、mal 1c分配的內存區域、block代碼塊和C++對象中的至少一項。當然,上述僅為舉例,并不作限制。
[0030]確定預置對象后,獲取該預置對象的內存地址。其中,獲取的方法有多種。例如,1s系統中通過 malloc_zone_malloc、malloc_zone_valloc^Pmalloc_zone_calloci_5f函數來分配堆內存,本實施例中,通過hook該三個函數,在自定義的函數中記錄預置對象的內存地址。
[0031]可選的,本實施例中,還獲取該預置對象的內存大小、堆棧信息、類名(若該預置對象有類名)等等。其中,可根據線程堆棧回溯方法獲取該預置對象的分配堆棧。
[0032]獲取到預置對象的內存地址后,該預置對象的內存地址存儲到第一數據結構中。例如,以該預置對象的內存地址為key值存儲到全局哈希表中。
[0033]103、獲取指針變量集合,所述指針變量集合包括內存空間中的所有指針變量。
[0034]獲取指針變量集合的方法有多種。例如,對目標區域進行掃描,其中,該目標區域為包含所有指針變量的內存區域。例如,在1s進程虛擬內存空間中,該目標區域包括堆內存、棧內存、全局數據區和寄存器該四個內存區域。
[0035]又例如,對目標區域進行掃描,查找第一指針變量集合,將所述第一指針變量集合加入所述指針變量集合中,其中,所述目標區域包括棧內存、全局數據區和寄存器,所述第一指針變量集合為所述目標區域內的所有指針變量。確定第一指針變量集合后,遍歷所述第一指針變量集合,對所述第一指針變量集合中的每一個特定指針變量,所述特定指針變量為指向堆內存中任意一個區域的指針變量,執行步驟A:
[0036]對所述特定指針變量指向的區域進行掃描;將所述區域中的所有指針變量加入所述指針變量集合中;當所述所有指針變量中存在所述特定指針變量,且所述特定指針變量不是指向自身所在區域時,對所述特定指針變量重復所述步驟A,當所述所有指針變量中不存在不是指向自身所在區域的特定指針變量時,停止重復所述步驟A。
[0037]104、檢測所述第一數據結構中是否存在不被所述指針變量集合中的任一指針變量指向的內存地址。
[0038]對于指針變量集合中的任意一個指針變量,確認該指針變量所指向的內存地址是否存在第一數據結構中。這樣,可以確認指針變量集合所指向的第一數據結構中的所有內存地址。具體的,對指針變量集合中的任意一個指針變量,若該指針變量指向第一數據結構中的其中一個內存地址,則對該內存地址進行標識,那么對指針變量集合遍歷完后,第一數據結構中沒有被標識的內存地址為不被指針變量集合中任一指針變量指向的內存地址。
[0039 ] 105、若存在,則確定內存泄漏,并確定所述內存地址中的對象為泄漏對象。
[0040]本實施例中,記錄對象的內存地址,并創建第一數據結構來存儲這些信息,通過分析所有包含指針變量的內存區域中的指針變量,對于沒有指針變量指向的對象,可認為在進程空間中無引用的對象,因此,當第一數據結構中存在沒有指針變量指向的對象時,確定該對象為泄漏對象,這樣,通過本發明中的檢測內存泄漏方法移動終端可以獨立檢測內存泄漏而無需依賴其他工具。
[0041 ]可選的,本實施例中,當檢測到所述第一數據結構中的對象被釋放時,如將所述對象的分配地址和堆棧信息從所述第一數據結構中刪除。這樣可以保證在第一數據結構中存儲的為當前進程的駐留內存對象。其中,檢測的方法有多種,例如,1s系統中通過malloc_zone_freec函數來釋放內存對象,本實施例中,通過hook該函數,在自定義的函數中確定所釋放的對象是否在第一數據結構中。
[0042]為方便理解,下面結合圖2和圖3對本實施例中步驟103的一種實施方式以及結合圖4對本實施例中的步驟104的一種實施方式進行舉例描述。如圖2所示,圖2為本發明的檢測內存泄漏的方法中的獲取指針變量集合的方法的一種實施例的流程示意圖。本實施例中,獲取指針變量集合的方法包括:
[0043]建立掃描線程,并在掃描線程開始前掛起除掃描線程以外的其他所有線程。在該掃描線程中,遍歷目標區域。具體的,以1s系統為例,目標區域包括堆內存、棧內存、全局數據區和寄存器。在遍歷目標區域時,對堆內存中的所有可能包含指針的堆區域進行掃描;對于棧內存,對棧頂至棧起始地址之間的內存區域進行掃描;對全局數據區中所有mach-o文件的DATA數據段進行掃描;對寄存器,對所有通用寄存器進行掃描。將目標區域中掃描到的指針變量加入指針變量集合中。
[0044]本實施例中,第一數據結構中還包括每一個對象的引用計數,其中,每個對象的引用計數的初始值均為O。對指針變量集合中的每一個指針變量,檢測該指針變量指向的內存地址是否存在第一數據結構中,若存在,則對該內存地址對應的對象的引用計數加I。重復該步驟,直至遍歷完目標區域時結束掃描線程,并恢復其他所有線程。
[0045]本實施例中,通過在掃描前掛起除掃描線程外的所有線程,能夠避免在掃描目標區域時多線程內存訪問沖突。
[0046]如圖3所示,圖3為本發明的檢測內存泄漏的方法中的獲取指針變量集合的方法的另一種實施例的流程示意圖。本實施例中,獲取指針變量集合的方法包括:
[0047]建立掃描線程,并在掃描線程開始前掛起除掃描線程以外的其他所有線程。在該掃描線程中:
[0048]對目標區域進行掃描,查找第一指針變量集合,將所述第一指針變量集合加入所述指針變量集合中,其中,所述第一指針變量集合為所述目標區域內的所有指針變量,所述目標區域包括棧內存、全局數據區和寄存器。遍歷所述第一指針變量集合,對所述第一指針變量集合中的每一個特定指針變量,所述特定指針變量為指向堆內存中任意一個區域的指針變量,執行步驟A:
[0049]對所述特定指針變量指向的區域進行掃描;將所述區域中的所有指針變量加入所述指針變量集合中;當所述所有指針變量中存在所述特定指針變量,且所述特定指針變量不是指向所在區域時,對所述特定指針變量重復所述步驟A,當所述所有指針變量中不存在不是指向所在區域的特定指針變量時,停止重復所述步驟A。
[0050]本實施例中,第一數據結構中還包括每一個對象的引用計數,其中,每個對象的引用計數的初始值均為O。對指針變量集合中的每一個指針變量,檢測該指針變量指向的內存地址是否存在第一數據結構中,若存在,則對該內存地址對應的對象的引用計數加I。重復該步驟,直至遍歷完目標區域時結束掃描線程,并恢復其他所有線程。
[0051]相比圖2所示實施例,本實施例中不僅能檢測到無引用的泄漏對象,還能檢測到由于循環引用導致的泄漏。
[0052]如圖4所示,圖4為本發明的檢測內存泄漏的方法中的確認泄漏對象的方法的一種實施例的流程示意圖。本實施例中,確認泄漏對象的方法包括:
[0053]從第一數據結構的入口開始遍歷每一個對象,判斷該對象的引用計數是否為O,若是,則將該對象確認為泄漏對象,若否,則確認該對象不是泄漏對象。重復該步驟,直至遍歷完第一數據結構中的對象時,輸出第一數據結構中所有泄漏對象的信息。具體的,若第一數據結構中僅存儲有對象的內存地址,則該泄漏對象的信息包括泄漏對象的內存地址。若第一數據結構中存儲有對象的內存地址和其他信息(例如類名、分配堆棧等),則該泄漏對象的信息包括泄漏對象的內存地址和其他信息。
[0054]可選的,在本發明的檢測內存泄漏的方法中,在獲取預置對象的內存地址時,還獲取所述預置對象的堆棧信息和/或類名,并將該對象的堆棧信息和/或類名存儲到第一數據結構中。在確定泄漏對象之后,從第一數據結構取出該泄漏對象的堆棧信息和/或類名,并將所述泄漏對象的分配地址、堆棧信息和/或類名發送至預置分析平臺,以便所述預置分析平臺根據所述泄漏對象的分配地址和堆棧信息對泄漏源進行定位。
[0055]上面對本發明的檢測內存泄漏的方法進行了描述,下面對本發明的檢測內存泄漏的裝置進行描述。
[0056]參閱圖5,圖5為本發明的檢測內存泄漏的裝置的一個實施例的結構示意圖。本實施例中,檢測內存泄漏的裝置500包括:
[0057]創建模塊501,用于創建第一數據結構;
[0058]第一獲取模塊502,用于獲取預置對象的內存地址,將所述預置對象的存儲地址和堆棧信息存儲到所述第一數據結構中;
[0059]第二獲取模塊503,用于獲取指針變量集合,所述指針變量集合包括內存空間中的所有指針變量;
[0060]檢測模塊504,用于檢測所述第一數據結構中是否存在不被所述指針變量集合中的任一指針變量指向的內存地址;
[0061 ]確定模塊505,用于當所述第一數據結構中存在不被所述指針變量集合中的任一指針變量指向的內存地址時,確定內存泄漏,并確定所述內存地址中的對象為泄漏對象。
[0062]本實施例中,記錄對象的內存地址,并創建第一數據結構來存儲這些信息,通過分析所有包含指針變量的內存區域中的指針變量,對于沒有指針變量指向的對象,可認為在進程空間中無引用的對象,因此,當第一數據結構中存在沒有指針變量指向的對象時,確定該對象為泄漏對象,這樣,通過本發明中的檢測內存泄漏方法移動終端可以獨立檢測內存泄漏而無需依賴其他工具。
[0063]可選的,所述檢測內存泄漏的裝置500還包括:
[0064]刪除模塊506,用于當檢測到所述第一數據結構中的對象被釋放時,將所述對象的分配地址和堆棧信息從所述第一數據結構中刪除。
[0065]可選的,所述預置對象為objective-c類對象、mal1c分配的內存區域、block代碼塊和C++對象中的至少一項。
[0066]可選的,如圖6所示,所述檢測內存泄漏的裝置還包括:
[0067]第三獲取模塊601,用于獲取所述預置對象的堆棧信息和/或類名;
[0068]發送模塊602,用于在所述確定泄漏對象之后,將所述泄漏對象的分配地址、堆棧信息和/或類名發送至預置分析平臺,以便所述預置分析平臺根據所述泄漏對象的分配地址和堆棧信息對泄漏源進行定位。
[0069]可選的,所述第二獲取模塊具體用于對目標區域進行掃描,查找出所述目標區域內的所有指針變量,其中,所述目標區域包括堆內存、棧內存、全局數據區和寄存器。
[0070]可選的,所述第二獲取模塊具體用于:
[0071 ]對目標區域進行掃描,查找第一指針變量集合,將所述第一指針變量集合加入所述指針變量集合中,其中,所述第一指針變量集合為所述目標區域內的所有指針變量,所述目標區域包括棧內存、全局數據區和寄存器;
[0072]遍歷所述第一指針變量集合,對所述第一指針變量集合中的每一個特定指針變量,所述特定指針變量為指向堆內存中任意一個區域的指針變量,執行步驟A:
[0073]對所述特定指針變量指向的區域進行掃描;將所述所有指針變量加入所述指針變量集合中;當所述所有指針變量中存在所述特定指針變量,且所述特定指針變量不是指向所在區域時,對所述特定指針變量重復所述步驟A,當所述所有指針變量中不存在不是指向所在區域的特定指針變量時,停止重復所述步驟A。
[0074]可選的,所述第二獲取模塊在對目標區域進行掃描時,具體用于建立掃描線程并掛起除所述掃描線程以外的所有線程。
[0075]所屬領域的技術人員可以清楚地了解到,為描述的方便和簡潔,上述描述的系統,裝置和單元的具體工作過程,可以參考前述方法實施例中的對應過程,在此不再贅述。
[0076]在本申請所提供的幾個實施例中,應該理解到,所揭露的系統,裝置和方法,可以通過其它的方式實現。例如,以上所描述的裝置實施例僅僅是示意性的,例如,所述單元的劃分,僅僅為一種邏輯功能劃分,實際實現時可以有另外的劃分方式,例如多個單元或組件可以結合或者可以集成到另一個系統,或一些特征可以忽略,或不執行。另一點,所顯示或討論的相互之間的耦合或直接耦合或通信連接可以是通過一些接口,裝置或單元的間接耦合或通信連接,可以是電性,機械或其它的形式。
[0077]所述作為分離部件說明的單元可以是或者也可以不是物理上分開的,作為單元顯示的部件可以是或者也可以不是物理單元,即可以位于一個地方,或者也可以分布到多個網絡單元上。可以根據實際的需要選擇其中的部分或者全部單元來實現本實施例方案的目的。
[0078]另外,在本發明各個實施例中的各功能單元可以集成在一個處理單元中,也可以是各個單元單獨物理存在,也可以兩個或兩個以上單元集成在一個單元中。上述集成的單元既可以采用硬件的形式實現,也可以采用軟件功能單元的形式實現。
[0079]所述集成的單元如果以軟件功能單元的形式實現并作為獨立的產品銷售或使用時,可以存儲在一個計算機可讀取存儲介質中。基于這樣的理解,本發明的技術方案本質上或者說對現有技術做出貢獻的部分或者該技術方案的全部或部分可以以軟件產品的形式體現出來,該計算機軟件產品存儲在一個存儲介質中,包括若干指令用以使得一臺計算機設備(可以是個人計算機,服務器,或者網絡設備等)執行本發明各個實施例所述方法的全部或部分步驟。而前述的存儲介質包括:U盤、移動硬盤、只讀存儲器(ROM,Read-OnlyMemory)、隨機存取存儲器(RAM,Random Access Memory)、磁碟或者光盤等各種可以存儲程序代碼的介質。
[0080]以上所述,以上實施例僅用以說明本發明的技術方案,而非對其限制;盡管參照前述實施例對本發明進行了詳細的說明,本領域的普通技術人員應當理解:其依然可以對前述各實施例所記載的技術方案進行修改,或者對其中部分技術特征進行等同替換;而這些修改或者替換,并不使相應技術方案的本質脫離本發明各實施例技術方案的精神和范圍。
【主權項】
1.一種檢測內存泄漏的方法,其特征在于,包括: 創建第一數據結構; 獲取預置對象的內存地址,將所述預置對象的存儲地址和堆棧信息存儲到所述第一數據結構中; 獲取指針變量集合,所述指針變量集合包括內存空間中的所有指針變量; 檢測所述第一數據結構中是否存在不被所述指針變量集合中的任一指針變量指向的內存地址; 若存在,則確定內存泄漏,并確定所述內存地址中的對象為泄漏對象。2.根據權利要求1所述的檢測內存泄漏的方法,其特征在于, 當檢測到所述第一數據結構中的對象被釋放時,將所述對象的分配地址和堆棧信息從所述第一數據結構中刪除。3.根據權利要求1所述的檢測內存泄漏的方法,其特征在于, 所述預置對象為object i ve_c類對象、mal 1c分配的內存區域、block代碼塊和C++對象中的至少一項。4.據權利要求1所述的檢測內存泄漏的方法,其特征在于,所述檢測內存泄漏的方法還包括:獲取所述預置對象的堆棧信息和/或類名; 所述確定泄漏對象,之后還包括: 將所述泄漏對象的分配地址、堆棧信息和/或類名發送至預置分析平臺,以便所述預置分析平臺根據所述泄漏對象的分配地址和堆棧信息對泄漏源進行定位。5.根據權利要求1所述的檢測內存泄漏的方法,其特征在于,所述獲取指針變量集合,包括: 對目標區域進行掃描,查找出所述目標區域內的所有指針變量,其中,所述目標區域包括堆內存、棧內存、全局數據區和寄存器。6.根據權利要求1所述的檢測內存泄漏的方法,其特征在于,所述獲取指針變量集合,包括: 對目標區域進行掃描,查找第一指針變量集合,將所述第一指針變量集合加入所述指針變量集合中,其中,所述第一指針變量集合為所述目標區域內的所有指針變量,所述目標區域包括棧內存、全局數據區和寄存器; 遍歷所述第一指針變量集合,對所述第一指針變量集合中的每一個特定指針變量,所述特定指針變量為指向堆內存中任意一個區域的指針變量,執行步驟A: 對所述特定指針變量指向的區域進行掃描;將所述所有指針變量加入所述指針變量集合中;當所述所有指針變量中存在所述特定指針變量,且所述特定指針變量不是指向所在區域時,對所述特定指針變量重復所述步驟A,當所述所有指針變量中不存在不是指向所在區域的特定指針變量時,停止重復所述步驟A。7.根據權利要求5或6所述的檢測內存泄漏的方法,其特征在于,所述對目標區域進行掃描,包括: 建立掃描線程并掛起除所述掃描線程以外的所有線程。8.一種檢測內存泄漏的裝置,其特征在于,包括: 創建模塊,用于創建第一數據結構; 第一獲取模塊,用于獲取預置對象的內存地址,將所述預置對象的存儲地址和堆棧信息存儲到所述第一數據結構中; 第二獲取模塊,用于獲取指針變量集合,所述指針變量集合包括內存空間中的所有指針變量; 檢測模塊,用于檢測所述第一數據結構中是否存在不被所述指針變量集合中的任一指針變量指向的內存地址; 確定模塊,用于當所述第一數據結構中存在不被所述指針變量集合中的任一指針變量指向的內存地址時,確定內存泄漏,并確定所述內存地址中的對象為泄漏對象。9.根據權利要求8所述的檢測內存泄漏的裝置,其特征在于,所述檢測內存泄漏的裝置還包括: 刪除模塊,用于當檢測到所述第一數據結構中的對象被釋放時,將所述對象的分配地址和堆棧信息從所述第一數據結構中刪除。10.根據權利要求8所述的檢測內存泄漏的裝置,其特征在于, 所述預置對象為object i ve_c類對象、mal 1c分配的內存區域、block代碼塊和C++對象中的至少一項。11.據權利要求8所述的檢測內存泄漏的裝置,其特征在于,所述檢測內存泄漏的裝置還包括: 第三獲取模塊,用于獲取所述預置對象的堆棧信息和/或類名; 發送模塊,用于在所述確定泄漏對象之后,將所述泄漏對象的分配地址、堆棧信息和/或類名發送至預置分析平臺,以便所述預置分析平臺根據所述泄漏對象的分配地址和堆棧信息對泄漏源進行定位。12.根據權利要求8所述的檢測內存泄漏的裝置,其特征在于,所述第二獲取模塊具體用于對目標區域進行掃描,查找出所述目標區域內的所有指針變量,其中,所述目標區域包括堆內存、棧內存、全局數據區和寄存器。13.根據權利要求8所述的檢測內存泄漏的裝置,其特征在于,所述第二獲取模塊具體用于: 對目標區域進行掃描,查找第一指針變量集合,將所述第一指針變量集合加入所述指針變量集合中,其中,所述第一指針變量集合為所述目標區域內的所有指針變量,所述目標區域包括棧內存、全局數據區和寄存器; 遍歷所述第一指針變量集合,對所述第一指針變量集合中的每一個特定指針變量,所述特定指針變量為指向堆內存中任意一個區域的指針變量,執行步驟A: 對所述特定指針變量指向的區域進行掃描;將所述所有指針變量加入所述指針變量集合中;當所述所有指針變量中存在所述特定指針變量,且所述特定指針變量不是指向所在區域時,對所述特定指針變量重復所述步驟A,當所述所有指針變量中不存在不是指向所在區域的特定指針變量時,停止重復所述步驟A。14.根據權利要求12或13所述的檢測內存泄漏的裝置,其特征在于,所述第二獲取模塊在對目標區域進行掃描時,具體用于建立掃描線程并掛起除所述掃描線程以外的所有線程。
【文檔編號】G06F11/36GK106055478SQ201610377342
【公開日】2016年10月26日
【申請日】2016年5月31日
【發明人】羅鑫
【申請人】騰訊科技(深圳)有限公司