本發(fā)明涉及計(jì)算機(jī)技術(shù)領(lǐng)域,尤其涉及一種內(nèi)存泄漏的檢測(cè)方法和裝置。
背景技術(shù):
內(nèi)存泄漏是指功能模塊持續(xù)申請(qǐng)內(nèi)存空間,當(dāng)結(jié)束該功能后,該功能申請(qǐng)的內(nèi)存空間未能回收。內(nèi)存泄漏的出現(xiàn)會(huì)導(dǎo)致內(nèi)存不斷上漲,最終引發(fā)系統(tǒng)強(qiáng)行結(jié)束應(yīng)用,釋放內(nèi)存。強(qiáng)行結(jié)束應(yīng)用導(dǎo)致應(yīng)用異常退出,降低用戶體驗(yàn)。
在現(xiàn)有技術(shù)中,通過(guò)人工測(cè)試來(lái)檢測(cè)內(nèi)存泄漏。但是,人工測(cè)試偶然性,很難測(cè)試出所有內(nèi)存泄漏問(wèn)題。并且,人工測(cè)試環(huán)境與實(shí)際應(yīng)用環(huán)境存在差異,且人工測(cè)試在投入市場(chǎng)前須完成,故人工測(cè)試很難還原內(nèi)存泄漏的實(shí)際情況。
所以,由于現(xiàn)有技術(shù)依賴人工檢測(cè)內(nèi)存泄漏,所以導(dǎo)致檢測(cè)內(nèi)存泄漏和解決內(nèi)存泄漏周期長(zhǎng)。
技術(shù)實(shí)現(xiàn)要素:
發(fā)明實(shí)施例提供了一種內(nèi)存泄漏的檢測(cè)方法和裝置,用于實(shí)現(xiàn)自動(dòng)檢測(cè)內(nèi)存泄漏的技術(shù)效果。
第一方面,本發(fā)明提供了一種內(nèi)存泄漏的檢測(cè)方法,包括:
內(nèi)存檢測(cè)模塊對(duì)目標(biāo)應(yīng)用的每個(gè)作業(yè)Activity進(jìn)行監(jiān)控;
當(dāng)監(jiān)控到任一所述Activity退出,且所述Activity的一條或多條引用未被清除時(shí),確定所述目標(biāo)應(yīng)用存在內(nèi)存泄漏;
將未被清除的所述一條或多條引用一一傾卸到所述目標(biāo)應(yīng)用的一個(gè)或多個(gè)二進(jìn)制轉(zhuǎn)儲(chǔ)文件hprof文件中,所述hprof文件能夠表示出一條引用的引用關(guān)系;
基于每個(gè)所述hprof文件表示所述hprof文件存儲(chǔ)的引用的引用關(guān)系,確定出每條所述引用的引用鏈;
從一條或多條所述引用鏈中確定出導(dǎo)致內(nèi)存泄漏的引用鏈。
可選的,基于每個(gè)所述hprof文件表示所述hprof文件存儲(chǔ)的引用的引用關(guān)系,確定出每條所述引用的引用鏈,包括:
解析每個(gè)所述hprof文件,獲得每個(gè)所述hprof文件的引用鍵,所述hprof文件通過(guò)所述引用鍵表示所述引用關(guān)系;
基于每個(gè)所述引用鍵,確定每個(gè)所述引用的直接引用函數(shù);
計(jì)算每個(gè)所述直接引用函數(shù)到用于回收內(nèi)存的垃圾回收函數(shù)的最短路徑,所述最短路徑為所述引用鏈。
可選的,從一條或多條所述引用鏈中確定出導(dǎo)致內(nèi)存泄漏的引用鏈,包括:
判斷每個(gè)所述引用鏈的長(zhǎng)度是否超過(guò)1;
當(dāng)所述引用鏈的長(zhǎng)度超過(guò)1時(shí),確定所述引用鏈為所述導(dǎo)致內(nèi)存泄漏的引用鏈。
可選的,在將未被清除的所述一條或多條引用一一傾卸到所述目標(biāo)應(yīng)用的一個(gè)或多個(gè)二進(jìn)制轉(zhuǎn)儲(chǔ)文件hprof文件中之前,還包括:
調(diào)用垃圾回收函數(shù)清除一個(gè)或多個(gè)所述引用;
當(dāng)存在未能被所述垃圾回收函數(shù)清除的一個(gè)或多個(gè)所述引用時(shí),執(zhí)行所述將未被清除的所述一條或多條引用一一傾卸到所述目標(biāo)應(yīng)用的一個(gè)或多個(gè)二進(jìn)制轉(zhuǎn)儲(chǔ)文件hprof文件中的步驟。
可選的,從一個(gè)或多個(gè)所述引用鏈中確定出導(dǎo)致內(nèi)存泄漏的引用鏈之后,還包括:
將所述導(dǎo)致內(nèi)存泄漏的引用鏈記錄在報(bào)告文件中;
向與所述目標(biāo)應(yīng)用關(guān)聯(lián)的服務(wù)器發(fā)送所述報(bào)告文件。
可選的,所述內(nèi)存檢測(cè)模塊對(duì)應(yīng)的代碼插樁在所述目標(biāo)應(yīng)用的代碼中,且所述內(nèi)存檢測(cè)模塊的代碼與所述目標(biāo)應(yīng)用的代碼在同一級(jí)目錄下。
可選的,所述方法還包括:
所述目標(biāo)應(yīng)用在主線程中執(zhí)行,所述內(nèi)存檢測(cè)模塊在不同于主線程的內(nèi)存檢測(cè)線程中執(zhí)行。
第二方面,本發(fā)明提供了一種內(nèi)存泄漏的檢測(cè)裝置,包括:
監(jiān)控單元,用于對(duì)目標(biāo)應(yīng)用的每個(gè)作業(yè)Activity進(jìn)行監(jiān)控;
第一確定單元,用于當(dāng)監(jiān)控到任一所述Activity退出,且所述Activity的一條或多條引用未被清除時(shí),確定所述目標(biāo)應(yīng)用存在內(nèi)存泄漏;
傾卸單元,用于將未被清除的所述一條或多條引用一一傾卸到所述目標(biāo)應(yīng)用的一個(gè)或多個(gè)二進(jìn)制轉(zhuǎn)儲(chǔ)文件hprof文件中,所述hprof文件能夠表示出一條引用的引用關(guān)系;
第二確定單元,用于基于每個(gè)所述hprof文件表示所述hprof文件存儲(chǔ)的引用的引用關(guān)系,確定出每條所述引用的引用鏈;
第三確定單元,用于從一條或多條所述引用鏈中確定出導(dǎo)致內(nèi)存泄漏的引用鏈。
可選的,所述第二確定單元用于解析每個(gè)所述hprof文件,獲得每個(gè)所述hprof文件的引用鍵,所述hprof文件通過(guò)所述引用鍵表示所述引用關(guān)系;基于每個(gè)所述引用鍵,確定每個(gè)所述引用的直接引用函數(shù);計(jì)算每個(gè)所述直接引用函數(shù)到用于回收內(nèi)存的垃圾回收函數(shù)的最短路徑,所述最短路徑為所述引用鏈。
可選的,所述第三確定單元用于判斷每個(gè)所述引用鏈的長(zhǎng)度是否超過(guò)1;當(dāng)所述引用鏈的長(zhǎng)度超過(guò)1時(shí),確定所述引用鏈為所述導(dǎo)致內(nèi)存泄漏的引用鏈。
可選的,所述裝置還包括:
篩選單元,用于在將未被清除的所述一條或多條引用一一傾卸到所述目標(biāo)應(yīng)用的一個(gè)或多個(gè)二進(jìn)制轉(zhuǎn)儲(chǔ)文件hprof文件中之前,調(diào)用垃圾回收函數(shù)清除一個(gè)或多個(gè)所述引用;當(dāng)存在未能被所述垃圾回收函數(shù)清除的一個(gè)或多個(gè)所述引用時(shí),通知傾卸單元將未被清除的所述一條或多條引用一一傾卸到所述目標(biāo)應(yīng)用的一個(gè)或多個(gè)二進(jìn)制轉(zhuǎn)儲(chǔ)文件hprof文件中的步驟。
可選的,所述裝置還包括:
記錄單元,用于從一個(gè)或多個(gè)所述引用鏈中確定出導(dǎo)致內(nèi)存泄漏的引用鏈之后,將所述導(dǎo)致內(nèi)存泄漏的引用鏈記錄在報(bào)告文件中;
發(fā)送單元,用于向與所述目標(biāo)應(yīng)用關(guān)聯(lián)的服務(wù)器發(fā)送所述報(bào)告文件。
本申請(qǐng)實(shí)施例中的上述一個(gè)或多個(gè)技術(shù)方案,至少具有如下一種或多種技術(shù)效果:
在本發(fā)明實(shí)施例的技術(shù)方案中,內(nèi)存檢測(cè)模塊對(duì)目標(biāo)應(yīng)用的每個(gè)作業(yè)Activity進(jìn)行監(jiān)控,當(dāng)監(jiān)控到任一Activity退出,且所述Activity的一條或多條引用未被清除時(shí),確定目標(biāo)應(yīng)用存在內(nèi)存泄漏,然后將未被清除的一條或多條引用一一傾卸到目標(biāo)應(yīng)用的一個(gè)或多個(gè)二進(jìn)制轉(zhuǎn)儲(chǔ)文件hprof文件中,hprof文件能夠表示出一條引用的引用關(guān)系,進(jìn)而基于每個(gè)hprof文件表示hprof文件存儲(chǔ)的引用的引用關(guān)系,確定出每條引用的引用鏈,并從一條或多條引用鏈中確定出導(dǎo)致內(nèi)存泄漏的引用鏈。由上述描述看出,本發(fā)明實(shí)施例通過(guò)內(nèi)存檢測(cè)模塊實(shí)現(xiàn)了自動(dòng)檢測(cè)內(nèi)存泄漏,并且根據(jù)hprof文件表示的引用關(guān)系確定出確定出導(dǎo)致內(nèi)存泄漏的引用鏈,實(shí)現(xiàn)了定位內(nèi)存泄漏的所在位置。由此,解決了現(xiàn)有技術(shù)檢測(cè)內(nèi)存泄漏依賴人工的技術(shù)問(wèn)題,實(shí)現(xiàn)了自動(dòng)檢測(cè)并定位內(nèi)存泄漏的技術(shù)效果。
附圖說(shuō)明
圖1為本發(fā)明實(shí)施例中內(nèi)存泄漏的檢測(cè)方法流程圖;
圖2為本發(fā)明實(shí)施例中一示例性函數(shù)拓?fù)涫疽鈭D;
圖3為本發(fā)明實(shí)施例中內(nèi)存泄漏的檢測(cè)裝置結(jié)構(gòu)示意圖。
具體實(shí)施方式
發(fā)明實(shí)施例提供了一種內(nèi)存泄漏的檢測(cè)方法和裝置,用于實(shí)現(xiàn)自動(dòng)檢測(cè)內(nèi)存泄漏的技術(shù)效果。
為了解決上述技術(shù)問(wèn)題,本發(fā)明提供的技術(shù)方案總體思路如下:
在本發(fā)明實(shí)施例的技術(shù)方案中,內(nèi)存檢測(cè)模塊對(duì)目標(biāo)應(yīng)用的每個(gè)作業(yè)Activity進(jìn)行監(jiān)控,當(dāng)監(jiān)控到任一Activity退出,且所述Activity的一條或多條引用未被清除時(shí),確定目標(biāo)應(yīng)用存在內(nèi)存泄漏,然后將未被清除的一條或多條引用一一傾卸到目標(biāo)應(yīng)用的一個(gè)或多個(gè)二進(jìn)制轉(zhuǎn)儲(chǔ)文件hprof文件中,hprof文件能夠表示出一條引用的引用關(guān)系,進(jìn)而基于每個(gè)hprof文件表示hprof文件存儲(chǔ)的引用的引用關(guān)系,確定出每條引用的引用鏈,并從一條或多條引用鏈中確定出導(dǎo)致內(nèi)存泄漏的引用鏈。由上述描述看出,本發(fā)明實(shí)施例通過(guò)內(nèi)存檢測(cè)模塊實(shí)現(xiàn)了自動(dòng)檢測(cè)內(nèi)存泄漏,并且根據(jù)hprof文件表示的引用關(guān)系確定出確定出導(dǎo)致內(nèi)存泄漏的引用鏈,實(shí)現(xiàn)了定位內(nèi)存泄漏的所在位置。由此,解決了現(xiàn)有技術(shù)檢測(cè)內(nèi)存泄漏依賴人工的技術(shù)問(wèn)題,實(shí)現(xiàn)了自動(dòng)檢測(cè)并定位內(nèi)存泄漏的技術(shù)效果。
下面通過(guò)附圖以及具體實(shí)施例對(duì)本發(fā)明技術(shù)方案做詳細(xì)的說(shuō)明,應(yīng)當(dāng)理解本申請(qǐng)實(shí)施例以及實(shí)施例中的具體特征是對(duì)本申請(qǐng)技術(shù)方案的詳細(xì)的說(shuō)明,而不是對(duì)本申請(qǐng)技術(shù)方案的限定,在不沖突的情況下,本申請(qǐng)實(shí)施例以及實(shí)施例中的技術(shù)特征可以相互組合。
本文中術(shù)語(yǔ)“和/或”,僅僅是一種描述關(guān)聯(lián)對(duì)象的關(guān)聯(lián)關(guān)系,表示可以存在三種關(guān)系,例如,A和/或B,可以表示:?jiǎn)为?dú)存在A,同時(shí)存在A和B,單獨(dú)存在B這三種情況。另外,本文中字符“/”,一般表示前后關(guān)聯(lián)對(duì)象是一種“或”的關(guān)系。
本發(fā)明第一方面提供了一種內(nèi)存泄漏的檢測(cè)方法,請(qǐng)參考圖1,為本發(fā)明實(shí)施例中內(nèi)存泄漏的檢測(cè)方法流程圖。該方法包括:
S101:內(nèi)存檢測(cè)模塊對(duì)目標(biāo)應(yīng)用的每個(gè)作業(yè)Activity進(jìn)行監(jiān)控;
S102:當(dāng)監(jiān)控到任一所述Activity退出,且所述Activity的一條或多條引用未被清除時(shí),確定所述目標(biāo)應(yīng)用存在內(nèi)存泄漏;
S103:將未被清除的所述一條或多條引用一一傾卸到所述目標(biāo)應(yīng)用的一個(gè)或多個(gè)二進(jìn)制轉(zhuǎn)儲(chǔ)文件hprof文件中,所述hprof文件能夠表示出一條引用的引用關(guān)系;
S104:基于每個(gè)所述hprof文件表示所述hprof文件存儲(chǔ)的引用的引用關(guān)系,確定出每條所述引用的引用鏈;
S105:從一條或多條所述引用鏈中確定出導(dǎo)致內(nèi)存泄漏的引用鏈。
具體來(lái)講,為了便于在用戶使用目標(biāo)應(yīng)用過(guò)程中對(duì)目標(biāo)應(yīng)用內(nèi)存泄漏進(jìn)行檢測(cè),本發(fā)明實(shí)施例中的內(nèi)存檢測(cè)模塊運(yùn)行在目標(biāo)應(yīng)用中。具體來(lái)講,在本發(fā)明實(shí)施例中,使用Python語(yǔ)言編寫內(nèi)存檢測(cè)模塊的代碼。Python是一種面向?qū)ο蟆⒔忉屝陀?jì)算機(jī)程序設(shè)計(jì)語(yǔ)言。Python語(yǔ)法簡(jiǎn)潔而清晰,具有豐富和強(qiáng)大的類庫(kù)。它常被昵稱為膠水語(yǔ)言,能夠把用其他語(yǔ)言制作的各種模塊很輕松地聯(lián)結(jié)在一起。編寫好的內(nèi)存檢測(cè)模塊代碼再利用gradle或ANT進(jìn)行編譯,最后插樁到目標(biāo)應(yīng)用的代碼中。
其中,如果利用ANT的編譯方式進(jìn)行編譯,則具體為將內(nèi)存檢測(cè)模塊的代碼編譯打包為canary.jar包,然后將canary.jar包插樁到目標(biāo)應(yīng)用的代碼中。其中,canary.jar包是爪哇JAVA語(yǔ)言搜集ANR(應(yīng)用程序無(wú)響應(yīng),Application Not Responding)信息日志的工具編譯而成的。或者,如果利用gradle的編譯方式進(jìn)行編譯,則無(wú)需打包,直接將內(nèi)存檢測(cè)模塊的代碼插樁到目標(biāo)應(yīng)用的代碼中即可。在具體實(shí)現(xiàn)過(guò)程中,本發(fā)明所屬領(lǐng)域的普通技術(shù)人員可以根據(jù)實(shí)際進(jìn)行選擇gradle、ANT或者其他編譯方式,本發(fā)明不做具體限制。
進(jìn)一步,為了避免內(nèi)存檢測(cè)模塊對(duì)目標(biāo)應(yīng)用程序的正常運(yùn)行產(chǎn)生影響,在本發(fā)明實(shí)施例中,將內(nèi)存檢測(cè)模塊的代碼和目標(biāo)應(yīng)用程序的代碼放置在同一級(jí)目錄中。在運(yùn)行目標(biāo)應(yīng)用時(shí),目標(biāo)應(yīng)用運(yùn)行在主線程中,為用戶提供目標(biāo)應(yīng)用的各個(gè)功能。而內(nèi)存檢測(cè)模塊則運(yùn)行在不同于主線程的內(nèi)存檢測(cè)線程中,進(jìn)而使得內(nèi)存檢測(cè)線程中執(zhí)行的各個(gè)操作不會(huì)影響主線程,進(jìn)而不影響目標(biāo)應(yīng)用的正常運(yùn)行。
上述對(duì)目標(biāo)應(yīng)用的改進(jìn)完成后,與目標(biāo)應(yīng)用關(guān)聯(lián)的服務(wù)器將改進(jìn)后的目標(biāo)應(yīng)用發(fā)送到各個(gè)應(yīng)用下載平臺(tái)或UE(用戶設(shè)備,User Equipment)。進(jìn)而UE從應(yīng)用下載平臺(tái)或者服務(wù)器中下載目標(biāo)應(yīng)用,并將目標(biāo)應(yīng)用安裝到UE中。由于目標(biāo)應(yīng)用中插樁了內(nèi)存檢測(cè)模塊,因此目標(biāo)應(yīng)用在UE中運(yùn)行時(shí),目標(biāo)應(yīng)用就可以自動(dòng)對(duì)目標(biāo)應(yīng)用的內(nèi)存泄漏進(jìn)行檢測(cè)和定位。
下面就對(duì)如何對(duì)內(nèi)存泄漏檢測(cè)和定位進(jìn)行具體介紹。
首先,S101中,在目標(biāo)應(yīng)用運(yùn)行過(guò)程中,內(nèi)存檢測(cè)模塊也會(huì)隨目標(biāo)應(yīng)用的運(yùn)行而運(yùn)行,進(jìn)而對(duì)目標(biāo)應(yīng)用的每個(gè)作業(yè)Activity進(jìn)行監(jiān)控。具體來(lái)講,本發(fā)明實(shí)施例中的內(nèi)存檢測(cè)模塊具有引用鏈監(jiān)控方法RefWatcher.watch()方法。利用RefWatcher.watch()方法在每個(gè)Activity中創(chuàng)建能夠監(jiān)控Activity的弱引用鍵值KeyedWeakReference對(duì)象,進(jìn)而Activity在初始化Oncreat函數(shù)中初始化時(shí),KeyedWeakReference對(duì)象也同時(shí)被初始化。
在正常情況下,Activity退出后,該Activity的全部引用將會(huì)被回收清除,進(jìn)而釋放該Activity申請(qǐng)的內(nèi)存。因此,當(dāng)KeyedWeakReference監(jiān)測(cè)到Activity退出,然而該Activity的一條或多條引用卻未被全部清除時(shí),則S102中確定目標(biāo)應(yīng)用出現(xiàn)了內(nèi)存泄漏。
為了定位導(dǎo)致內(nèi)存泄漏的原因,進(jìn)一步,在S103中,將未被清除的一條或多個(gè)引用傾卸到目標(biāo)應(yīng)用的系統(tǒng)文件中的hprof文件中。具體為一條引用傾卸到一個(gè)hprof文件中。換言之,一個(gè)Activity的hprof文件的數(shù)量,為該Activity未被清除的引用數(shù)量。二進(jìn)制轉(zhuǎn)儲(chǔ)文件hprof文件是一種快照存儲(chǔ)類型的文件,它包含了所有數(shù)據(jù)表現(xiàn)方式,以及JAVA對(duì)象和線程內(nèi)部的基本數(shù)據(jù)類型,記錄對(duì)象中域的值和hprof文件生成時(shí)有哪些方法在被執(zhí)行。正是由于hprof文件的特性,使得hprof文件能夠表示引用的引用關(guān)系。
所以,S104中,基于每個(gè)hprof文件,確定出每條引用的引用鏈。在本發(fā)明實(shí)施例中,S104通過(guò)如下過(guò)程實(shí)現(xiàn):
解析每個(gè)所述hprof文件,獲得每個(gè)所述hprof文件的引用鍵,所述hprof文件通過(guò)所述引用鍵表示所述引用關(guān)系;
基于每個(gè)所述引用鍵,確定每個(gè)所述引用的直接引用函數(shù);
計(jì)算每個(gè)所述直接引用函數(shù)到用于回收內(nèi)存的垃圾回收函數(shù)的最短路徑,所述最短路徑為所述引用鏈。
首先對(duì)hprof文件進(jìn)行解析,解析出hprof文件中唯一的引用鍵reference key。其中,hprof文件正是通過(guò)reference key來(lái)表示引用關(guān)系,通過(guò)reference key可以指示出這條引用的直接引用函數(shù)。在本發(fā)明實(shí)施例中,直接引用函數(shù)指的是直接引用Activity的函數(shù)。舉例來(lái)說(shuō),函數(shù)A通過(guò)引用函數(shù)B進(jìn)而引用函數(shù)C,而函數(shù)C引用了Activity,則函數(shù)C就是Activity的直接引用函數(shù)。因此,基于每個(gè)引用鍵可以確定出每條引用的直接引用函數(shù)。
接下來(lái),計(jì)算直接引用函數(shù)到GC(垃圾回收,Gabage,collection)函數(shù)的最短路徑。GC函數(shù)是用于在Activity退出后回收該Activity的各條引用的函數(shù)。引用不能被GC函數(shù)回收,表示引用所在的引用鏈異常,引發(fā)內(nèi)存泄漏。其中,本發(fā)明實(shí)施例中直接引用函數(shù)到GC函數(shù)之間的最短路徑就是引用鏈。
具體來(lái)講,由于目標(biāo)應(yīng)用中存在大量的函數(shù),且大部分函數(shù)可以引用其他函數(shù),以及被其他函數(shù)引用,所以,直接引用函數(shù)到GC函數(shù)的路徑就有多條。舉例來(lái)說(shuō),圖2示出一函數(shù)拓?fù)涫疽鈭D。在圖2中,直接引用函數(shù)為A函數(shù),A函數(shù)到GC函數(shù)可以有兩條路徑,第一條為“A函數(shù)-B函數(shù)-C函數(shù)-GC函數(shù)”,第二條為“A函數(shù)-D函數(shù)-GC函數(shù)”。由于第一條路徑引用了三次才到達(dá)GC函數(shù),而第二條路徑僅引用兩次就到達(dá)GC函數(shù),所以第二條路徑最短,所以第二條路徑是A函數(shù)的引用鏈。通過(guò)類似的方式,獲得每條引用的引用鏈,進(jìn)而總共獲得一條或多條引用鏈。
確定出引用鏈之后,執(zhí)行S105,從一條或多條引用鏈中確定出存在內(nèi)存泄漏的引用鏈。具體來(lái)講,本發(fā)明實(shí)施例中的S105通過(guò)如下過(guò)程實(shí)現(xiàn):
判斷每個(gè)所述引用鏈的長(zhǎng)度是否超過(guò)1;
當(dāng)所述引用鏈的長(zhǎng)度超過(guò)1時(shí),確定所述引用鏈為所述導(dǎo)致內(nèi)存泄漏的引用鏈。
具體來(lái)講,判斷引用鏈的長(zhǎng)度是否超過(guò)1,進(jìn)而判斷引用鏈?zhǔn)欠駥?dǎo)致了內(nèi)存泄漏。在本發(fā)明實(shí)施例中,引用鏈的長(zhǎng)度指的是直接引用函數(shù)到GC函數(shù)總共引用函數(shù)的次數(shù)。舉例來(lái)說(shuō),圖2中的第一條路徑的長(zhǎng)度為3,第二條路徑的長(zhǎng)度為2。
當(dāng)引用鏈長(zhǎng)度超過(guò)1時(shí),表示直接引用函數(shù)不能被GC函數(shù)所直接引用,進(jìn)而表示直接引用函數(shù)無(wú)法被GC函數(shù)直接清除,因此該引用鏈導(dǎo)致了內(nèi)存泄漏。所以,在本發(fā)明實(shí)施例中,將長(zhǎng)度超過(guò)1的引用鏈作為引用內(nèi)存泄漏的引用鏈。
進(jìn)一步,為了能夠更好地維護(hù)目標(biāo)應(yīng)用,作為一種可選的實(shí)施例,在S105之后,還可以包括:
將所述導(dǎo)致內(nèi)存泄漏的引用鏈記錄在報(bào)告文件中;
向與所述目標(biāo)應(yīng)用關(guān)聯(lián)的服務(wù)器發(fā)送所述報(bào)告文件。
具體來(lái)講,將導(dǎo)致內(nèi)存泄漏的引用鏈保存在UE中的報(bào)告文件中,并且將報(bào)告文件發(fā)送給目標(biāo)應(yīng)用關(guān)聯(lián)的服務(wù)器。由此使得服務(wù)器的管理人員通過(guò)查看報(bào)告文件中的一條或多個(gè)引用鏈,進(jìn)而還原出內(nèi)存泄漏的情況,從而修復(fù)內(nèi)存泄漏的問(wèn)題。
或者,為了提示用戶目標(biāo)應(yīng)用出現(xiàn)內(nèi)存泄漏,作為一種可選的實(shí)施例,在S105之后,還可以輸出表示內(nèi)存泄漏的提示信息。具體來(lái)講,提示信息以及輸出提示信息的方式有多種。例如可以將導(dǎo)致內(nèi)存泄漏的引用鏈傳入為顯示泄漏服務(wù)DisplayLeakService函數(shù),進(jìn)而以通知欄顯示通知的形式輸出文字提示信息?;蛘?,也可以調(diào)用音頻輸出函數(shù)輸出異常提示音。本發(fā)明所屬領(lǐng)域的普通技術(shù)人員可以根據(jù)實(shí)際選擇,本發(fā)明不做具體限制。
較佳地,作為一種可選的實(shí)施例,在將未被清除的一條或多條引用一一傾卸到hprof文件中之前,還可以包括:
調(diào)用垃圾回收函數(shù)清除一個(gè)或多個(gè)所述引用;
當(dāng)存在未能被所述垃圾回收函數(shù)清除的一個(gè)或多個(gè)所述引用時(shí),執(zhí)行所述將未被清除的所述一條或多條引用一一傾卸到所述目標(biāo)應(yīng)用的一個(gè)或多個(gè)二進(jìn)制轉(zhuǎn)儲(chǔ)文件hprof文件中的步驟。
具體來(lái)講,在具體實(shí)現(xiàn)過(guò)程中,Activity退出后,不能被清除的引用也可以并不是由于內(nèi)存泄漏而導(dǎo)致不能被清除,因此,為了篩選出是由于內(nèi)存泄漏而不能清除的引用,同時(shí)降低后續(xù)定位內(nèi)存泄漏的計(jì)算量,在Activity退出后,內(nèi)存檢測(cè)線程如果檢測(cè)到Activity的引用沒(méi)有被全部清除,則調(diào)用GC函數(shù)對(duì)這些未能被清除的引用再次嘗試清除。
此時(shí),對(duì)于并非內(nèi)存泄漏導(dǎo)致不能被清除的引用將順利被內(nèi)存檢測(cè)線程創(chuàng)建的GC函數(shù)清除,而此時(shí)依然未能被GC函數(shù)清除的一條或多條引用,則就是由于內(nèi)存泄漏而導(dǎo)致不能清除的引用了。所以,通過(guò)上述過(guò)程就篩選出了真正定位內(nèi)存泄漏需要的引用,同時(shí)也降低了后續(xù)處理的數(shù)據(jù)量。
基于與前述實(shí)施例中內(nèi)存泄漏的檢測(cè)方法同樣的發(fā)明構(gòu)思,本發(fā)明第二方面還提供一種內(nèi)存泄漏的檢測(cè)裝置,如圖3所示,包括:
監(jiān)控單元101,用于對(duì)目標(biāo)應(yīng)用的每個(gè)作業(yè)Activity進(jìn)行監(jiān)控;
第一確定單元102,用于當(dāng)監(jiān)控到任一所述Activity退出,且所述Activity的一條或多條引用未被清除時(shí),確定所述目標(biāo)應(yīng)用存在內(nèi)存泄漏;
傾卸單元103,用于將未被清除的所述一條或多條引用一一傾卸到所述目標(biāo)應(yīng)用的一個(gè)或多個(gè)二進(jìn)制轉(zhuǎn)儲(chǔ)文件hprof文件中,所述hprof文件能夠表示出一條引用的引用關(guān)系;
第二確定單元104,用于基于每個(gè)所述hprof文件表示所述hprof文件存儲(chǔ)的引用的引用關(guān)系,確定出每條所述引用的引用鏈;
第三確定單元105,用于從一條或多條所述引用鏈中確定出導(dǎo)致內(nèi)存泄漏的引用鏈。
具體來(lái)講,第二確定單元104用于解析每個(gè)所述hprof文件,獲得每個(gè)所述hprof文件的引用鍵,所述hprof文件通過(guò)所述引用鍵表示所述引用關(guān)系;基于每個(gè)所述引用鍵,確定每個(gè)所述引用的直接引用函數(shù);計(jì)算每個(gè)所述直接引用函數(shù)到用于回收內(nèi)存的垃圾回收函數(shù)的最短路徑,所述最短路徑為所述引用鏈。
具體來(lái)講,第三確定單元105用于判斷每個(gè)所述引用鏈的長(zhǎng)度是否超過(guò)1;當(dāng)所述引用鏈的長(zhǎng)度超過(guò)1時(shí),確定所述引用鏈為所述導(dǎo)致內(nèi)存泄漏的引用鏈。
進(jìn)一步,本發(fā)明實(shí)施例中的內(nèi)存泄漏的檢測(cè)裝置還可以包括:
篩選單元,用于在將未被清除的所述一條或多條引用一一傾卸到所述目標(biāo)應(yīng)用的一個(gè)或多個(gè)二進(jìn)制轉(zhuǎn)儲(chǔ)文件hprof文件中之前,調(diào)用垃圾回收函數(shù)清除一個(gè)或多個(gè)所述引用;當(dāng)存在未能被所述垃圾回收函數(shù)清除的一個(gè)或多個(gè)所述引用時(shí),通知傾卸單元將未被清除的所述一條或多條引用一一傾卸到所述目標(biāo)應(yīng)用的一個(gè)或多個(gè)二進(jìn)制轉(zhuǎn)儲(chǔ)文件hprof文件中的步驟。
更進(jìn)一步,本發(fā)明實(shí)施例中的內(nèi)存泄漏的檢測(cè)裝置還可以包括:
記錄單元,用于從一個(gè)或多個(gè)所述引用鏈中確定出導(dǎo)致內(nèi)存泄漏的引用鏈之后,將所述導(dǎo)致內(nèi)存泄漏的引用鏈記錄在報(bào)告文件中;
發(fā)送單元,用于向與所述目標(biāo)應(yīng)用關(guān)聯(lián)的服務(wù)器發(fā)送所述報(bào)告文件。
前述圖1-圖2實(shí)施例中的內(nèi)存泄漏的檢測(cè)方法的各種變化方式和具體實(shí)例同樣適用于本實(shí)施例的內(nèi)存泄漏的檢測(cè)裝置,通過(guò)前述對(duì)內(nèi)存泄漏的檢測(cè)方法的詳細(xì)描述,本領(lǐng)域技術(shù)人員可以清楚的知道本實(shí)施例中內(nèi)存泄漏的檢測(cè)裝置的實(shí)施方法,所以為了說(shuō)明書的簡(jiǎn)潔,在此不再詳述。
本申請(qǐng)實(shí)施例中的上述一個(gè)或多個(gè)技術(shù)方案,至少具有如下一種或多種技術(shù)效果:
在本發(fā)明實(shí)施例的技術(shù)方案中,內(nèi)存檢測(cè)模塊對(duì)目標(biāo)應(yīng)用的每個(gè)作業(yè)Activity進(jìn)行監(jiān)控,當(dāng)監(jiān)控到任一Activity退出,且所述Activity的一條或多條引用未被清除時(shí),確定目標(biāo)應(yīng)用存在內(nèi)存泄漏,然后將未被清除的一條或多條引用一一傾卸到目標(biāo)應(yīng)用的一個(gè)或多個(gè)二進(jìn)制轉(zhuǎn)儲(chǔ)文件hprof文件中,hprof文件能夠表示出一條引用的引用關(guān)系,進(jìn)而基于每個(gè)hprof文件表示hprof文件存儲(chǔ)的引用的引用關(guān)系,確定出每條引用的引用鏈,并從一條或多條引用鏈中確定出導(dǎo)致內(nèi)存泄漏的引用鏈。由上述描述看出,本發(fā)明實(shí)施例通過(guò)內(nèi)存檢測(cè)模塊實(shí)現(xiàn)了自動(dòng)檢測(cè)內(nèi)存泄漏,并且根據(jù)hprof文件表示的引用關(guān)系確定出確定出導(dǎo)致內(nèi)存泄漏的引用鏈,實(shí)現(xiàn)了定位內(nèi)存泄漏的所在位置。由此,解決了現(xiàn)有技術(shù)檢測(cè)內(nèi)存泄漏依賴人工的技術(shù)問(wèn)題,實(shí)現(xiàn)了自動(dòng)檢測(cè)并定位內(nèi)存泄漏的技術(shù)效果。
本領(lǐng)域內(nèi)的技術(shù)人員應(yīng)明白,本發(fā)明的實(shí)施例可提供為方法、系統(tǒng)、或計(jì)算機(jī)程序產(chǎn)品。因此,本發(fā)明可采用完全硬件實(shí)施例、完全軟件實(shí)施例、或結(jié)合軟件和硬件方面的實(shí)施例的形式。而且,本發(fā)明可采用在一個(gè)或多個(gè)其中包含有計(jì)算機(jī)可用程序代碼的計(jì)算機(jī)可用存儲(chǔ)介質(zhì)(包括但不限于磁盤存儲(chǔ)器、CD-ROM、光學(xué)存儲(chǔ)器等)上實(shí)施的計(jì)算機(jī)程序產(chǎn)品的形式。
本發(fā)明是參照根據(jù)本發(fā)明實(shí)施例的方法、設(shè)備(系統(tǒng))、和計(jì)算機(jī)程序產(chǎn)品的流程圖和/或方框圖來(lái)描述的。應(yīng)理解可由計(jì)算機(jī)程序指令實(shí)現(xiàn)流程圖和/或方框圖中的每一流程和/或方框、以及流程圖和/或方框圖中的流程和/或方框的結(jié)合??商峁┻@些計(jì)算機(jī)程序指令到通用計(jì)算機(jī)、專用計(jì)算機(jī)、嵌入式處理機(jī)或其他可編程數(shù)據(jù)處理設(shè)備的處理器以產(chǎn)生一個(gè)機(jī)器,使得通過(guò)計(jì)算機(jī)或其他可編程數(shù)據(jù)處理設(shè)備的處理器執(zhí)行的指令產(chǎn)生用于實(shí)現(xiàn)在流程圖一個(gè)流程或多個(gè)流程和/或方框圖一個(gè)方框或多個(gè)方框中指定的功能的裝置。
這些計(jì)算機(jī)程序指令也可存儲(chǔ)在能引導(dǎo)計(jì)算機(jī)或其他可編程數(shù)據(jù)處理設(shè)備以特定方式工作的計(jì)算機(jī)可讀存儲(chǔ)器中,使得存儲(chǔ)在該計(jì)算機(jī)可讀存儲(chǔ)器中的指令產(chǎn)生包括指令裝置的制造品,該指令裝置實(shí)現(xiàn)在流程圖一個(gè)流程或多個(gè)流程和/或方框圖一個(gè)方框或多個(gè)方框中指定的功能。
這些計(jì)算機(jī)程序指令也可裝載到計(jì)算機(jī)或其他可編程數(shù)據(jù)處理設(shè)備上,使得在計(jì)算機(jī)或其他可編程設(shè)備上執(zhí)行一系列操作步驟以產(chǎn)生計(jì)算機(jī)實(shí)現(xiàn)的處理,從而在計(jì)算機(jī)或其他可編程設(shè)備上執(zhí)行的指令提供用于實(shí)現(xiàn)在流程圖一個(gè)流程或多個(gè)流程和/或方框圖一個(gè)方框或多個(gè)方框中指定的功能的步驟。
顯然,本領(lǐng)域的技術(shù)人員可以對(duì)本發(fā)明進(jìn)行各種改動(dòng)和變型而不脫離本發(fā)明的精神和范圍。這樣,倘若本發(fā)明的這些修改和變型屬于本發(fā)明權(quán)利要求及其等同技術(shù)的范圍之內(nèi),則本發(fā)明也意圖包含這些改動(dòng)和變型在內(nèi)。