專利名稱:用于內(nèi)存泄漏診斷的方法和裝置的制作方法
技術(shù)領(lǐng)域:
本發(fā)明涉及一種用于垃圾收集語(yǔ)言的內(nèi)存泄漏診斷的方法和裝置。
背景技術(shù):
在一些編程語(yǔ)言以及相關(guān)的運(yùn)行時(shí)間(runtime)中,通常會(huì)由應(yīng)用程序 本身提供一種內(nèi)存管理功能。對(duì)于那不再被程序需要的內(nèi)存是由程序設(shè)計(jì)員 來(lái)釋放。如果程序不能合理釋放不同的內(nèi)存將導(dǎo)致內(nèi)存資源的浪費(fèi),即這些 內(nèi)存將不能被任何其他的程序使用。導(dǎo)致這種內(nèi)存浪費(fèi)的程序錯(cuò)誤通常稱之 為"內(nèi)存泄漏"。在有些編程語(yǔ)言中,會(huì)采用自動(dòng)內(nèi)存管理而不是依賴程序員 釋放內(nèi)存。這種自動(dòng)內(nèi)存管理在本領(lǐng)域通常稱之為"垃圾收集",就是一種與 編程語(yǔ)言以及其相關(guān)的運(yùn)行時(shí)間的實(shí)施相關(guān)的運(yùn)行時(shí)間系統(tǒng)的主動(dòng)元件。這
員部分地從釋放內(nèi)存的管理工作中解脫出來(lái)。但是,自動(dòng)內(nèi)存管理會(huì)產(chǎn)生另 一個(gè)問(wèn)題,就是有些對(duì)象保留對(duì)部分內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)的引用(reference),
動(dòng)垃圾收集器回收那些不再被使用的內(nèi)存部分,也導(dǎo)致了 "內(nèi)存泄漏"。因 此,盡管垃圾收集機(jī)制幫助減少了 "內(nèi)存泄漏"問(wèn)題,但是后一種內(nèi)存泄漏 仍舊存在并導(dǎo)致計(jì)算機(jī)的性能降低,嚴(yán)重的時(shí)候會(huì)導(dǎo)致應(yīng)用程序的運(yùn)行占用 所有的內(nèi)存并導(dǎo)致計(jì)算機(jī)崩潰。因此,內(nèi)存泄漏由于其對(duì)計(jì)算機(jī)的性能造成 巨大影響而削弱了計(jì)算機(jī)的可獲得性和安全性。
對(duì)于支持自動(dòng)內(nèi)存管理的運(yùn)行時(shí)間中的內(nèi)存泄漏,其主要以兩類方式存 在 一類是通過(guò)每次執(zhí)行而快速地創(chuàng)建大量的泄漏或以至于為人所覺(jué)察的方 式創(chuàng)建泄漏;另一類是通過(guò)每次執(zhí)行而連續(xù)微妙地以至于無(wú)法察覺(jué)地創(chuàng)建泄 漏。
如何發(fā)現(xiàn)和找到那些正在泄漏的對(duì)象以及快速找到泄漏的原因是本領(lǐng)域 需要解決的問(wèn)題。 一個(gè)系統(tǒng)的泄漏診斷起來(lái)是非常復(fù)雜的,尤其是對(duì)于那些 每次連續(xù)以及較小容量地發(fā)生的緩慢泄漏而言是如此。對(duì)于在堆上的不明顯
5的增長(zhǎng)是非常難以辨識(shí)的。通常,在發(fā)現(xiàn)泄漏時(shí)已經(jīng)為時(shí)已晚,泄漏程序已 經(jīng)對(duì)整個(gè)系統(tǒng)造成了嚴(yán)重的影響。這對(duì)于那種開始很小但是在整個(gè)運(yùn)行時(shí)間 段內(nèi)持續(xù)增長(zhǎng)的泄漏而言尤其如此。有時(shí),在問(wèn)題大到足以可注意之前需要 高達(dá)幾周的服務(wù)時(shí)間。識(shí)別這些潛在泄漏是非常困難的,尤其是對(duì)于不能忍
受多次堆(heap )訪問(wèn)甚至堆轉(zhuǎn)儲(chǔ)(dump )的在線系統(tǒng)(live productive system ) 而言是如此,因?yàn)檫@些系統(tǒng)不能忍受由于堆操作需要的執(zhí)行暫停。盡管現(xiàn)在 存在各種垃圾回收方式并且也各有益處,但是這種內(nèi)存泄漏對(duì)于Java程序而 言依然是一個(gè)問(wèn)題。
目前,現(xiàn)有的一些技術(shù)有助于用戶對(duì)黑箱進(jìn)行研究以便確定在運(yùn)行時(shí)間 (runtime)處的根本原因。對(duì)診斷內(nèi)存泄漏,現(xiàn)有技術(shù)主要依賴于比較區(qū)分 堆快照(snapshot)(堆快照是一種由像節(jié)點(diǎn)一樣的類型以及其間的引用構(gòu)成 的圖(graph))以及根據(jù)對(duì)象數(shù)量的增長(zhǎng)來(lái)進(jìn)行診斷。這些技術(shù)在每輪垃圾 收集之后監(jiān)視堆,并且觀察自由空間的向下的鋸齒圖形(內(nèi)存的使用率曲線 圖)直到程序無(wú)法在從堆上獲得空間為止(每次收集的、可供以后使用的內(nèi) 存越來(lái)越少)。這種現(xiàn)有的技術(shù)并不能用于在線系統(tǒng),因?yàn)檫@種堆快照的獲取 和分析會(huì)使得具有較大的堆容量的系統(tǒng)暫停幾十秒。對(duì)于諸如服務(wù)器的在線 系統(tǒng)而言,這種延遲或暫停會(huì)導(dǎo)致超時(shí),從而顯著影響在線應(yīng)用的表現(xiàn)?;?于上述原因,這種延遲和暫停對(duì)于在線系統(tǒng)而言是完全不可接受的。
而且,用于大型應(yīng)用程序的內(nèi)存堆往往容量巨大,因此,試圖對(duì)堆快照 進(jìn)行頻繁的比較對(duì)這些應(yīng)用程序的診斷幫助有限,因?yàn)樾孤?duì)象并不明顯, 但是如果利用現(xiàn)有技術(shù)進(jìn)行泄漏診斷,應(yīng)用程序會(huì)由于為進(jìn)行泄漏診斷而頻 繁進(jìn)行堆快照的比較操作而減慢,這將對(duì)服務(wù)質(zhì)量以及用戶的體驗(yàn)帶來(lái)負(fù)面
到很大干擾(perturb)以至于不具有實(shí)際價(jià)值,尤其是在在線環(huán)境下。
現(xiàn)有的內(nèi)存泄漏的診斷方法對(duì)工業(yè)應(yīng)用的效果有限,因?yàn)檫@些現(xiàn)有的方 法通常將基本類型識(shí)別為嫌疑類型。例如, 一種現(xiàn)有技術(shù)建議使用引用 (reference)來(lái)查找負(fù)責(zé)內(nèi)存泄漏的有用對(duì)象。但是引用不能包含執(zhí)行語(yǔ)境 信息。被引用的嫌疑對(duì)象因?yàn)槭腔镜某R娛褂妙愋停赡芡瑫r(shí)被多個(gè)引用 者持有。在這種情況下,人們依然不了解這些引用為什么會(huì)產(chǎn)生以及在何種 條件下泄漏問(wèn)題會(huì)被再現(xiàn)。診斷以及修復(fù)是否正確難以進(jìn)行判別。
在目前的實(shí)踐中, 一方面,依賴多次取得全引用圖快照并對(duì)其進(jìn)行引用分析對(duì)于大規(guī)模在線系統(tǒng)而言成本過(guò)于昂貴。另一方面,在發(fā)明人的經(jīng)驗(yàn)中, 為了診斷內(nèi)存泄漏,用戶必須尋找可能具有問(wèn)題的候選數(shù)據(jù)結(jié)構(gòu)。但是,發(fā) 現(xiàn)將要關(guān)注的正好的數(shù)據(jù)結(jié)構(gòu)非常困難。當(dāng)探尋服務(wù)(尤其是大型在線系統(tǒng)) 的引用圖時(shí),噪聲、復(fù)雜性以及規(guī)模問(wèn)題會(huì)使得引用圖的分析非常困難。當(dāng) 在長(zhǎng)時(shí)間運(yùn)行的系統(tǒng)中診斷緩慢的內(nèi)存泄漏時(shí),噪聲可能是一個(gè)特別的問(wèn)題。 噪聲影響可能會(huì)矮化診斷緩慢泄漏所需的證據(jù)直到其運(yùn)行了很久之后為止。
概括而言,現(xiàn)有技術(shù)方案主要集中在以下幾點(diǎn)反復(fù)訪問(wèn)堆甚至進(jìn)行堆
轉(zhuǎn)儲(chǔ)來(lái)產(chǎn)生堆快照、在不同的快照之間進(jìn)行比較以便找到作為泄漏候選的增 長(zhǎng)節(jié)點(diǎn)、找到嫌疑結(jié)構(gòu)、以及分析引用圖從而找到造成內(nèi)存被不當(dāng)持有的引 用者以便隨后進(jìn)行確認(rèn)。因此,目前針對(duì)內(nèi)存泄漏路徑所采取的方法通常包
括兩個(gè)步驟診斷并確認(rèn)診斷以及修復(fù)泄漏點(diǎn)。但是在診斷和確認(rèn)診斷之間 存在斷層(gap),現(xiàn)有技術(shù)在內(nèi)存泄漏診斷方面所能提供的幫助有限。 根據(jù)以上描述可知,現(xiàn)有的內(nèi)存泄漏診斷技術(shù)存在以下技術(shù)問(wèn)題
1. 效率低下?,F(xiàn)有的途徑需要用戶手動(dòng)將這些高速緩存對(duì)象與真正的泄 漏對(duì)象區(qū)分開??傮w而言,這些途徑使得用戶忙于應(yīng)付關(guān)于所創(chuàng)建的各個(gè)對(duì) 象的眾多低水平的細(xì)節(jié),普通用戶很難解釋復(fù)雜引用圖以獲得相關(guān)問(wèn)題執(zhí)行 環(huán)境。這些解釋處理需要大量的專門知識(shí)。即使對(duì)于專家而言,這也通常需 要進(jìn)行很長(zhǎng)時(shí)間的分析工作來(lái)發(fā)現(xiàn)泄漏的根本原因。
2. 堆訪問(wèn)會(huì)對(duì)所運(yùn)行的系統(tǒng)造成的干擾(perturbation )。這些技術(shù)在有 些情況下將使得運(yùn)行的系統(tǒng)不穩(wěn)定以至于不具有實(shí)際價(jià)值,尤其是在在線境 下。獲取引用圖后需要對(duì)堆快照?qǐng)?zhí)行比較分析,這些工作甚至可以造成具有 較大堆尺寸的系統(tǒng)暫停幾十秒。如前所述,對(duì)于服務(wù)器而言,這些延遲或暫 停會(huì)導(dǎo)致超時(shí)(timeout),并且顯著地改變系統(tǒng)的特性。
3. 基于堆增長(zhǎng)進(jìn)行泄漏分析受到限制。現(xiàn)有的一些工具利用堆的增長(zhǎng)和 對(duì)堆進(jìn)行區(qū)分來(lái)發(fā)現(xiàn)內(nèi)存泄漏,以便發(fā)現(xiàn)使得堆增長(zhǎng)的對(duì)象。盡管堆增長(zhǎng)是 有助于判別的有用的參數(shù),但是僅僅使用增長(zhǎng)作為一種啟發(fā)來(lái)發(fā)現(xiàn)泄漏依然 存在許多問(wèn)題。畢竟,增長(zhǎng)的對(duì)象或類型并不一定就是泄漏并且泄漏也并不 一定就會(huì)增長(zhǎng)。
4. 基于引用進(jìn)行的泄漏分析受到限制。僅僅知曉占支配地位的泄漏對(duì)象 的類型,通常是諸如"串型"的低級(jí)類型,對(duì)解釋為什么會(huì)發(fā)生內(nèi)存泄漏的 幫助有限,這是因?yàn)檫@些串可能被用于多個(gè)語(yǔ)境中,甚至可能在相同的數(shù)據(jù)結(jié)構(gòu)(例如DOM文件)中被用于多種用途。此外由于一個(gè)低級(jí)泄漏對(duì)象可 能同時(shí)被多個(gè)引用者不當(dāng)持有,因此很容易在分析引用圖、提取泄漏的原因
時(shí)導(dǎo)致迷失。單一的DOM對(duì)象包含有成千上萬(wàn)個(gè)對(duì)象,并且在其間存在豐 富的引用網(wǎng)絡(luò)。如果對(duì)架構(gòu)的實(shí)施不了解,就很難獲知要遵循引用路徑中的 那個(gè)路徑、獲知何時(shí)分析分配調(diào)用路徑、或者哪個(gè)調(diào)用位置是重要的。
5.基于類型分配堆棧進(jìn)行的泄漏分析受到限制。有些方法能夠通過(guò)監(jiān)視 堆而同時(shí)記錄每一個(gè)類型對(duì)象的分配堆棧,但并不是嫌疑類型的所有實(shí)例正 在泄漏,因此實(shí)際泄漏路徑趨向被淹沒(méi)在所有堆棧之間,并且存儲(chǔ)和分析這 些堆棧需要付出運(yùn)行時(shí)間和運(yùn)行空間的代價(jià)。通常,泄漏位置不是與分配位 置映射,而是與分配函數(shù)的調(diào)用者相映射。例如,Java數(shù)據(jù)庫(kù)連接(JDBC) 通過(guò)由一個(gè)類調(diào)用的一個(gè)代理類被反復(fù)地創(chuàng)建,所述調(diào)用的類會(huì)忘記調(diào)用該 代理類的JDBC釋放函數(shù)。這樣,就必須對(duì)調(diào)用者進(jìn)行分析。
綜上可見,現(xiàn)有技術(shù)現(xiàn)需要進(jìn)行復(fù)雜圖分析以及豐富的程序知識(shí),為泄 漏的確認(rèn)以及修復(fù)提供有限的線索。
本申請(qǐng)的目的在于解決現(xiàn)有技術(shù)中存在的上述技術(shù)問(wèn)題。
發(fā)明內(nèi)容
發(fā)明人注意到,現(xiàn)有的方法主要集中在內(nèi)存泄漏的查找,但是很少關(guān)注 與泄漏問(wèn)題直接相關(guān)的分配路徑的認(rèn)識(shí)。辨識(shí)其上可能發(fā)生泄漏的分配路徑 能夠直接獲得與泄漏分析相關(guān)的信息,指引用戶跟蹤嫌疑對(duì)象分配和使用。
基于以上認(rèn)識(shí)以及為了避免上述現(xiàn)有技術(shù)的缺點(diǎn),本發(fā)明提供了 一種能 夠用于活動(dòng)系統(tǒng)的內(nèi)存泄漏診斷裝置和方法。
根據(jù)本發(fā)明的一個(gè)方面,提供了一種用于診斷內(nèi)存泄露的方法,包括 跟蹤應(yīng)用程序在虛擬機(jī)上運(yùn)行過(guò)程中的對(duì)象分配,從而獲取并記錄對(duì)象的分 配路徑和分配時(shí)間;以預(yù)定的時(shí)間間隔計(jì)算每一類對(duì)象在其分配路徑的年齡 代數(shù);以及將其上具有高年齡代數(shù)對(duì)象的分配路徑確定為可能存在內(nèi)存泄漏 的分配路徑,并報(bào)告給用戶以進(jìn)行分析。
根據(jù)本發(fā)明的另一個(gè)方面,提供了一種診斷內(nèi)存泄漏的裝置,包括
對(duì)象分配跟蹤器件,跟蹤應(yīng)用程序在虛擬機(jī)上運(yùn)行過(guò)程中的對(duì)象分配, 從而獲取并記錄對(duì)象的分配路徑和分配時(shí)間;分配路徑記錄器件,用于記錄 從對(duì)象分配跟蹤器件傳送來(lái)的每個(gè)對(duì)象的分配路徑和分配時(shí)間;用于應(yīng)用程
8序的堆,用于存儲(chǔ)從分配路徑記錄器件傳送來(lái)的路徑分配的對(duì)象信息;分配
路徑讀取器件,用于讀取所述堆中路徑分配的對(duì)象信息,并掃描存儲(chǔ)器中存
儲(chǔ)的每個(gè)對(duì)象的id以及對(duì)應(yīng)的分配路徑信息,以便針對(duì)每條分配路徑整理由 它分配的、并且還沒(méi)有被回收的對(duì)象并根據(jù)每個(gè)對(duì)象的分配時(shí)間計(jì)算該路徑 所分配同一類對(duì)象的年齡代數(shù);分配路徑排序器件,用于根據(jù)每條路徑分配 的、并且存活的對(duì)象的年齡代數(shù)把路徑排序;以及診斷報(bào)告器件,用于對(duì)從 分配路徑排序器傳送來(lái)的分配路徑的排序數(shù)據(jù)進(jìn)行分析,并將高排序的分配 路徑確定為可能存在內(nèi)存泄漏的分配路徑報(bào)告給用戶以進(jìn)行分析。
根據(jù)本發(fā)明的另一個(gè)方面,還提供一種用于診斷內(nèi)存泄漏的裝置,包括 對(duì)象分配跟蹤器件,用于跟蹤應(yīng)用程序在虛擬機(jī)上運(yùn)行過(guò)程中的對(duì)象分 配,從而獲取對(duì)象的分配路徑和分配時(shí)間;分配路徑記錄器件,用于在每個(gè) 所分配的對(duì)象上打上包含其分配路徑與分配對(duì)象的對(duì)應(yīng)關(guān)系的標(biāo)簽;用于應(yīng) 用程序的堆,用于存儲(chǔ)從分配路徑記錄器件傳送來(lái)的路徑分配的對(duì)象信息; 分配路徑讀取器件,對(duì)每條分配路徑直接按照標(biāo)簽從所述堆中讀取由它分配 的、并且還沒(méi)有被回收的對(duì)象,并根據(jù)每個(gè)對(duì)象的分配時(shí)間計(jì)算該路徑所分 配同一類對(duì)象的年齡代數(shù);分配路徑排序器件,用于根據(jù)每條路徑分配的、
并且存活的對(duì)象的年齡代數(shù)把路徑排序;以及診斷報(bào)告器件,用于對(duì)從分配 路徑排序器傳送來(lái)的分配路徑的排序數(shù)據(jù)進(jìn)行分析,并將高排序的分配路徑 確定為可能存在內(nèi)存泄漏的分配路徑報(bào)告給用戶進(jìn)行分析。
下面參照附圖僅作為示例詳細(xì)描述本發(fā)明的實(shí)施例,其中
圖1表示在執(zhí)行應(yīng)用程序的過(guò)程中用于管理所分配對(duì)象的信息的數(shù)據(jù)結(jié)
構(gòu);
圖2所示的是本發(fā)明所使用的標(biāo)簽的結(jié)構(gòu)的示意圖。; 圖3所示的是在不同波段上的同類對(duì)象之間的調(diào)用關(guān)系的示意圖; 圖4所示的是提取每個(gè)對(duì)象的分配路徑以及將所述分配路徑與具體對(duì)象 進(jìn)行綁定的過(guò)程示意圖5所示的是不同位置層級(jí)的結(jié)構(gòu)以及進(jìn)行對(duì)象聚合的示意圖。 圖6所示的是診斷一個(gè)應(yīng)用程序所造成的內(nèi)存泄漏的流程圖 圖7所示的是用于診斷內(nèi)存泄漏的裝置的一個(gè)實(shí)施例。圖8所示的是用于診斷內(nèi)存泄漏的裝置的另 一個(gè)實(shí)施例。
具體實(shí)施例方式
現(xiàn)在將參考本發(fā)明的示例性實(shí)施例進(jìn)行詳細(xì)的描述,在附圖中圖解說(shuō)明 了所述實(shí)施例的示例,其中相同的參考數(shù)字始終指示相同的元件。應(yīng)當(dāng)理解, 本發(fā)明并不限于所公開的示例實(shí)施例。還應(yīng)當(dāng)理解,并非所述方法和設(shè)備的 每個(gè)特征對(duì)于實(shí)施任一權(quán)利要求所要求保護(hù)的本發(fā)明都是必要的。此外,在
整個(gè)公開中,當(dāng)顯示或描述處理或方法時(shí),方法的步驟可以以任何順序或者 同時(shí)執(zhí)行,除非從上下文中能清楚一個(gè)步驟依賴于先執(zhí)行的另一步驟。此外, 步驟之間可以有顯著的時(shí)間間隔。
申請(qǐng)人發(fā)現(xiàn),泄漏的對(duì)象通常屬于一種類型,并且該類型的實(shí)例在不同 的間隔期間被連續(xù)地生成、分配??紤]到這種情形,在本發(fā)明的方法中,首 先辨識(shí)與這種分配一致的類的類型。隨后,找到創(chuàng)建該類型的實(shí)例的路徑。 本發(fā)明關(guān)注在每一個(gè)相對(duì)較長(zhǎng)的間隔中連續(xù)創(chuàng)建的同一類對(duì)象。為了實(shí)現(xiàn)本 發(fā)明的目的,本發(fā)明提出了一種數(shù)據(jù)結(jié)構(gòu)對(duì)同一類型的對(duì)象分配進(jìn)行跟蹤, 如圖1所示。每種面向?qū)ο蟮膽?yīng)用程序都包含有不同類型的對(duì)象。針對(duì)每種 類型的對(duì)象,都構(gòu)建一種便于記錄其分配路徑的列表。這種數(shù)據(jù)結(jié)構(gòu)中包含 了類的簽名、對(duì)象計(jì)數(shù)、時(shí)間計(jì)數(shù)器以及分配路徑(一個(gè)對(duì)象的分配路徑是 其分配時(shí)刻的堆棧映象)。通過(guò)這種數(shù)據(jù)結(jié)構(gòu)對(duì)對(duì)象的分配進(jìn)行管理。
參見圖1,針對(duì)同一種類型的對(duì)象,在應(yīng)用程序的過(guò)程中可能在不同的 路徑上被分配。因此根據(jù)圖l所示的數(shù)據(jù)結(jié)構(gòu),針對(duì)每條分配路徑進(jìn)行跟蹤, 利用計(jì)數(shù)器記錄在該路徑上分配的對(duì)象數(shù)量,當(dāng)分配數(shù)量超過(guò)一定規(guī)模的時(shí) 候在計(jì)時(shí)器中記錄相應(yīng)的時(shí)刻。換句話說(shuō),計(jì)時(shí)器中記錄了分配數(shù)量連續(xù)到 達(dá)制定規(guī)模的時(shí)間間隔長(zhǎng)度。。對(duì)所述的對(duì)象的分配信息的跟蹤,可以通過(guò)后
面將結(jié)合圖6和7所詳細(xì)描述的對(duì)象分配跟蹤器件61來(lái)進(jìn)行。對(duì)于所跟蹤獲 得這種對(duì)象的信息,可以由將結(jié)合圖6和7所詳細(xì)描述的分配路徑記錄器件 62記錄起來(lái)并存儲(chǔ)到相應(yīng)的存儲(chǔ)器63中或直接發(fā)送到應(yīng)用程序的堆中。
對(duì)于所記錄的具有上述數(shù)據(jù)結(jié)構(gòu)的對(duì)象信息,可以采用專門的分配路徑 管理器件來(lái)進(jìn)行管理,也可以在直接將相關(guān)的對(duì)象信息發(fā)送到堆之前對(duì)每個(gè) 所分配的對(duì)象打上獨(dú)特的標(biāo)簽,以便將每個(gè)對(duì)象(即使是相同類的對(duì)象)區(qū) 分開來(lái)。圖2所示的就是本發(fā)明可以使用的這種標(biāo)簽的形式。針對(duì)每個(gè)所分配的對(duì)象的一個(gè)標(biāo)簽包^"了多個(gè)字^殳。就本發(fā)明所示的圖2中的實(shí)施例而言,
所述標(biāo)簽結(jié)構(gòu)中的第一字段是該對(duì)象的標(biāo)識(shí)符字段id,其表示了該對(duì)象屬于 哪個(gè)波段(band)以及那個(gè)組(group),倆者的組合唯一的標(biāo)志了該對(duì)象所 處的"年齡代數(shù)",其中對(duì)象的年齡是指從其被分配一直到被釋放的時(shí)間,其 年齡代數(shù)可以用該對(duì)象自分配起直到被回收所經(jīng)歷的"垃圾回收,,次數(shù)或者 該對(duì)象存在時(shí)間相對(duì)于某一預(yù)定時(shí)間閾值的倍數(shù)。在這里,默認(rèn)每一次垃圾 回收都會(huì)檢索所有在堆中分配內(nèi)存的對(duì)象。第二字段表示類字段,表示該對(duì) 象屬于那個(gè)類,例如圖l中所示的類l、類2、類3......等。第三字段屬于路
徑字段,表述該對(duì)象位于圖1中所示的哪個(gè)路徑上。第四字段是方法字段, 該方法字段并不是一種方法簽名的真實(shí)內(nèi)容,而是一個(gè)地址,指向方法簽名 的實(shí)際存貯。最后一個(gè)字段是被調(diào)用者字段,被用來(lái)尋找分配的路徑。該字 段與第四個(gè)字段結(jié)合,可以恢復(fù)出分配指定對(duì)象的路徑內(nèi)容。圖3就表示出 了如何基于不同年齡代數(shù)的對(duì)象標(biāo)簽,從調(diào)用關(guān)系字段和方法字段恢復(fù)出基 本的路徑信息。
下面,本發(fā)明將參照?qǐng)D4對(duì)本發(fā)明如何跟蹤對(duì)象分配以及分配路徑以及 如何在分配過(guò)程中計(jì)數(shù)進(jìn)行詳細(xì)的描述。
圖4所示的是提取每個(gè)對(duì)象的分配路徑以及將所述分配路徑與具體對(duì)象 進(jìn)行綁定標(biāo)簽的過(guò)程示意圖。在應(yīng)用程序運(yùn)行時(shí),對(duì)象的分配被跟蹤。對(duì)于 類型i的對(duì)象,當(dāng)該對(duì)象的總數(shù)達(dá)到鬮值H時(shí)記錄時(shí)間Ti,同時(shí)將該計(jì)數(shù)器 值重置為0。當(dāng)該對(duì)象的總數(shù)再次達(dá)到閾值H時(shí)記錄時(shí)間Ti+1。如果Ti和Tj+, 之間的差值超過(guò)閾值Tt時(shí),該類型i就被識(shí)別需要進(jìn)行下一階段的跟蹤記錄 過(guò)程,如果類型i進(jìn)入下一階段的記錄過(guò)程,分配i對(duì)象的路徑將被記錄下來(lái) 以及在該路徑上分配i類型對(duì)象的總數(shù)也被記錄。對(duì)于由路徑Pi所分配的類 型i的對(duì)象,在Pi上的當(dāng)前層級(jí)(tier,層級(jí)代表分配研究對(duì)象的堆棧位置, 因?yàn)槎褩J欠謱咏Y(jié)構(gòu)的,所以使用層級(jí)來(lái)標(biāo)志堆棧中的位置),在本發(fā)明中也 稱之為波段(band),的位置被標(biāo)簽到對(duì)象上。如果Tj和Tw之間的差值小于 閾值Tt時(shí),類型i的計(jì)數(shù)不變,隨著新實(shí)例的分配而增加。當(dāng)對(duì)象的總數(shù)在 時(shí)間Ti+I處再次達(dá)到閾值H時(shí)其數(shù)量并且Tj和Tj+,之間的差值超過(guò)閣值Tt 時(shí),該數(shù)量被重置為0,并且采用Tjw的值替代Tj,并且增加Pi上的層級(jí), 以便后面分配的對(duì)象將采用下一等級(jí)的位置來(lái)標(biāo)簽。如此對(duì)Pi上的的每個(gè)等 級(jí)的位置逐步地執(zhí)行相同的處理和判斷,以便這些等級(jí)將被標(biāo)簽在對(duì)象上。閾值Tt選擇對(duì)于在服務(wù)期間辨識(shí)壽命(lifetime)分布是非常有幫助的。 該默認(rèn)值被設(shè)定為平均GC (垃圾收集)間隔。Nt的選擇被用于安排對(duì)象分配 的規(guī)模或度量(scale ),這有助于發(fā)現(xiàn)用于相對(duì)頻繁地分配一種類型對(duì)象的路 徑。這種相對(duì)頻繁地分配一種類型的對(duì)象的分配路徑很可能與持續(xù)泄漏相關(guān)。 當(dāng)屬于 一種類型的對(duì)象被分配的總數(shù)超過(guò)閾值Nt時(shí),這種類型的對(duì)象被辨識(shí) 出來(lái)并且其分配路徑必須予以重視。當(dāng)在固定路徑中分配的對(duì)象的數(shù)量超過(guò) 閾值Nt時(shí),該路徑被辨識(shí)出來(lái)并通過(guò)將其自身與所創(chuàng)建的實(shí)例綁定起來(lái)而被 記錄。如果達(dá)到伐值的時(shí)間太短(<Tt),綁定到對(duì)象上的標(biāo)簽不變。如果時(shí) 間足夠長(zhǎng)(>=1\),新的標(biāo)簽將被給予被分配的對(duì)象。這種綁定間隔導(dǎo)致標(biāo)記 不同頻帶id和組id的組合的對(duì)象之間的分配時(shí)間至少長(zhǎng)于Tt。換句話說(shuō),組 id和頻帶id的組合唯一的標(biāo)記了不同年齡代數(shù)的對(duì)象。這種標(biāo)記方式直接有 助于在堆訪問(wèn)的同時(shí)進(jìn)行泄漏診斷,并輸出泄漏對(duì)象以及直接相關(guān)的泄漏路徑。
為了區(qū)分不同位置的層級(jí)(一個(gè)位置的層級(jí)表示其位于整個(gè)分配路徑上
例如,頻帶O被賦予位于分配路徑的頂部的分配位置,該位置直接創(chuàng)建對(duì)象, 而頻帶1則賦予調(diào)用頻帶0的位置的分配位置。這樣對(duì)診斷泄漏對(duì)象以及跟 蹤對(duì)象標(biāo)簽的分配路徑非常有用,該對(duì)象標(biāo)簽將在下面兩部分中引入。組id 被引入以防頻帶的值滿溢當(dāng)頻帶代表的層級(jí)數(shù)超過(guò)分配路徑的最大深度時(shí), 組id從0開始自增。頻帶值每滿溢一次,組id自增l。組id和頻帶id的組 合對(duì)于后面的診斷非常重要。圖5所示的就是這種層級(jí)的示意圖。
下面所示的程序代碼表示出了本發(fā)明是如何基于圖1中所示的結(jié)構(gòu)來(lái)跟 蹤管理對(duì)象的分配的,也是對(duì)上面的具體描述的一種程序表示。該程序代碼 在Java對(duì)象-陂分配時(shí)^f皮調(diào)用。
New—object ()
/*Get class signature of the object's class.*/ classSignature = GetClassSignature ()
/*Find the class index inhashTable, if it's not exist, putitintohashTable.*/ class工ndex = getAndPutClass ( classSignature ) /★Increase the object count of this class.*/ countClass (),'
/*If count of this class > Nt, count this ojbect to it's allocation path.*/ if( objectCount 〉 Mt ){ /*Find allocation path in this class structure, if it's not exist, put it into hashTsble.*/
getAndPutAllocationPath(); /*Tag this object with allocation path's band, class index, method of theband and its callee.V
tagObject(allocPathBand, class工ndex, methodOfBand, callee)/ "Increase the object count of this allocation path of this class ,*/ countAllocPath (),-
/*If the allocation path count 〉 Nt and time since last change of allocation path's band larger than Tt,then increase band of the allocation path, and reset its count, and update lastChangeTime*/
if( countOfAllocPath 〉 Nt && time—interval 〉 Tt ) moveToNextBand ()
}}
以上對(duì)對(duì)象的分配的跟蹤和記錄進(jìn)行詳細(xì)的描述。這種對(duì)各種類型的對(duì) 象的分配的跟蹤和記錄是為了便于在進(jìn)行診斷時(shí)發(fā)現(xiàn)泄漏對(duì)象以及發(fā)生泄漏 的路徑。在進(jìn)行診斷的時(shí)候,發(fā)現(xiàn)泄漏類以及泄漏的路徑是同時(shí)進(jìn)行的,而 不是分步進(jìn)行的?;趯?duì)對(duì)象分配的跟蹤和記錄,下面描述泄漏的診斷。
在進(jìn)行診斷之前,需要對(duì)應(yīng)用程序的虛擬機(jī)的堆進(jìn)行訪問(wèn)。經(jīng)過(guò)多次垃 圾回收當(dāng)前堆中僅保存有存活的對(duì)象信息。就本發(fā)明而言,包含有所分配對(duì) 象的類型、分配時(shí)間、分配路徑等信息。這些信息可以以上述與對(duì)象綁定的 標(biāo)簽的形式存在,也可以其他形式存在,例如可以專門設(shè)立一種分配路徑管 理器將按來(lái)管理每個(gè)對(duì)象的分配時(shí)間以及分配路徑直接的對(duì)應(yīng)關(guān)系。
總體而言,首先,將標(biāo)簽中基于頻帶id和組id的組合相同的對(duì)象聚合 (aggregate)成一組。接著從具有最高頻帶的對(duì)象從其標(biāo)簽的最后倆個(gè)字段 中恢復(fù)出這些對(duì)象的分配路徑。用這種方式找到的組數(shù)就是該路徑分配對(duì)象 的年齡跨度或者年齡代數(shù)。獲取該路徑中的對(duì)象分配跨度或代數(shù)(span)以 便用于診斷泄漏。采用這種方式,可同時(shí)找出泄漏對(duì)象以及泄漏路徑。
在較長(zhǎng)的運(yùn)行時(shí)間期間,泄漏導(dǎo)致在堆上具有不同年齡的相同類型的對(duì) 象的存在。對(duì)象的壽命是其幸免的垃圾回收的次數(shù)。該跨度計(jì)數(shù)是一種類型 的所有實(shí)例的不同壽命的數(shù)量或者代數(shù)。較低的跨度計(jì)數(shù)表示一類的所有實(shí) 例在存儲(chǔ)器內(nèi)已經(jīng)存在了相同的時(shí)間。較高的跨度計(jì)數(shù)表示該運(yùn)行的應(yīng)用程 序正繼續(xù)分配同一類新對(duì)象而沒(méi)釋放其更老的對(duì)象,程序通常不傾向于間隔 地分配長(zhǎng)時(shí)間存活的對(duì)象。相反,他們傾向于集中性地分配長(zhǎng)時(shí)間存活的對(duì) 象,或者分配對(duì)象只是為了在隨后很短一段時(shí)間使用,這些對(duì)象隨后一旦其 不再被需要就會(huì)立刻被清除。
基于以上理論,存活對(duì)象通過(guò)其標(biāo)簽被匯總以便診斷泄漏問(wèn)題。如在前 面所提到的那樣, 一個(gè)標(biāo)簽包括與分配路徑上的層級(jí)相關(guān)的位置的頻帶id以
13及與將路徑標(biāo)簽到對(duì)象上的滿溢次數(shù)(round)相關(guān)的組id。每一次垃圾收集 都會(huì)清除清除堆上那些不被引用的、"死亡"的對(duì)象。如上面所提到的那樣, 頻帶id以及組id的組合在不同時(shí)間間隔(至少間隔Tt)期間被綁定。時(shí)間 Tt與垃圾回收的時(shí)間間隔相關(guān),能夠用于標(biāo)識(shí)對(duì)象的年齡。這樣,標(biāo)簽中不 同頻帶id以及組id的組合區(qū)分了不同年齡的對(duì)象?;谝陨戏治?,所有標(biāo)簽 中擁有相同的頻帶id以及組id組合的對(duì)象被分到一組,這樣被一條分配路徑 分配的對(duì)象被分到若干組內(nèi)。分組的數(shù)量決定了該路徑分配的對(duì)象的年齡代 數(shù)。分配最大年齡代數(shù)的對(duì)象的那些路徑被辨識(shí)為候選泄漏路徑。具有這些 候選路徑標(biāo)簽的對(duì)象就是泄漏實(shí)例。圖5所示的是該聚合的處理過(guò)程。
在進(jìn)行聚合以及獲知了哪些是嫌疑泄漏類之后,需要采用與將標(biāo)簽路徑 綁定到對(duì)象上的處理相反的處理來(lái)確定分配中哪些是泄漏哪些不是泄漏,因 為分配位置以及分配路徑具體內(nèi)容對(duì)于診斷和修復(fù)泄漏來(lái)說(shuō)是有很大幫助 的,因此遍歷整個(gè)路徑是必須的。為了解決這個(gè)問(wèn)題,就要進(jìn)行與將標(biāo)簽路 徑綁定到對(duì)象上的處理相反的處理,從標(biāo)簽中恢復(fù)出確切的泄漏路徑。該恢 復(fù)過(guò)程可見圖3所示。從類型i的對(duì)象的最高頻帶為K (K>=1 )處的標(biāo)簽開 始,標(biāo)簽的一個(gè)字段(field)是"callee (被調(diào)用者)",其引用在頻帶(K-l) 處的方法,被在頻帶K處的方法調(diào)用。這樣迭代的恢復(fù)出原始分配路徑的各 層方法,所發(fā)現(xiàn)的方法鏈條就是分配路徑。也就是說(shuō),路徑的發(fā)現(xiàn)過(guò)程從最 高波段開始進(jìn)行。
圖6所示的是診斷一個(gè)應(yīng)用程序所造成的內(nèi)存泄漏的流程圖。首先運(yùn)行 一個(gè)應(yīng)用程序,并在步驟S601處, 一種如后面將要描述的內(nèi)存泄漏診斷裝置 隨著應(yīng)用程序開始運(yùn)行而開始監(jiān)測(cè)在應(yīng)用程序的運(yùn)行時(shí)間(runtime)處對(duì)象 的分配以及內(nèi)存的分配。在步驟S602處,內(nèi)存泄漏診斷裝置中的對(duì)象分配跟 蹤器件跟蹤應(yīng)用程序在虛擬機(jī)上運(yùn)行過(guò)程中的對(duì)象分配,并針對(duì)每一種類型 的對(duì)象,獲取該當(dāng)前對(duì)象的類型以及所分配的堆棧,為所有堆棧編碼唯一的 id以及為每個(gè)對(duì)象賦予一個(gè)與一條分配路徑相對(duì)應(yīng)的唯一的id,并將這種對(duì) 應(yīng)關(guān)系存儲(chǔ)起來(lái)。然后在步驟S603處,將其中包含了該對(duì)象的類型id、其堆 棧的id、以及指向頂部方法簽名的指針的標(biāo)簽與相應(yīng)的對(duì)象綁定在一起。該 頂部方法簽名并不在寄存器中。所有的方法簽名都被編碼并保存在代理中, 這種不同簽名的系列表示了各種分配路徑。因此,與對(duì)象綁定的標(biāo)簽包含了 該對(duì)象的分配路徑以及對(duì)象的類型。在步驟S604處,將所有對(duì)象的標(biāo)簽保存在一個(gè)列表中。具體而言,就是采用如后面所述的分配路徑管理器件來(lái)管理 該列表,從而管理列表中的標(biāo)簽中所包含的數(shù)據(jù),即對(duì)象的類型id、其堆棧
的id、以及指向頂部方法簽名的指針。在步驟S605處,經(jīng)過(guò)一個(gè)預(yù)訂的時(shí)間 間隔之后,例如經(jīng)過(guò)了自動(dòng)垃圾回收裝置執(zhí)行一次自動(dòng)垃圾回收的預(yù)定間隔 之后,用于由對(duì)象的類型id以及堆棧的id的id的寄存器被修改以便存儲(chǔ)具 有更高層級(jí)或波段的方法簽名,從而使得以后所分配的對(duì)象與在該間隔之前 所分配的對(duì)象具有不同的年齡代數(shù)。所述的時(shí)間間隔可以是預(yù)定時(shí)間間隔, 例如垃圾回收間隔。所述寄存器的改變也可以通過(guò)具體的事件來(lái)觸發(fā)。該具 體的時(shí)間可以是具有特定類型和堆棧的對(duì)象的總量達(dá)到了用戶根據(jù)其應(yīng)用程 序的存儲(chǔ)器使用規(guī)模所規(guī)定的某種閾值,也可以是某種需要專門關(guān)注的事件。 在步驟S606處,用戶需要進(jìn)行內(nèi)存泄漏診斷時(shí),通過(guò)后面將要描述的分配路 徑讀取器件,從一個(gè)存儲(chǔ)器中讀取關(guān)于標(biāo)簽的列表以及位于堆中的存活的分 配對(duì)象的信息。隨后在步驟S607中,從所讀取的標(biāo)簽列表中提取各個(gè)標(biāo)簽, 并將所有存活的分配對(duì)象按照標(biāo)簽聚合曽不同的組。然后在步驟S608處,對(duì) 每個(gè)具有相同標(biāo)簽的組中的對(duì)象的總量進(jìn)行排序,并將那些排序高的組中的 對(duì)象(即齡年代數(shù)較高的對(duì)象)所在的分配路徑確定為嫌疑的內(nèi)存泄漏路徑。 應(yīng)當(dāng)理解上述方法為本發(fā)明的優(yōu)選實(shí)施例,并非所有步驟對(duì)于解決本發(fā)明所
除非從上下文中能清楚一個(gè)步驟依賴于先執(zhí)行的另一步驟。此外,步驟之間 可以有顯著的時(shí)間間隔。
以上對(duì)本發(fā)明的內(nèi)存泄漏的診斷方法進(jìn)行了詳細(xì)的描述。相對(duì)于現(xiàn)有技 術(shù)而言,這些方法具有以下優(yōu)點(diǎn)用戶無(wú)需制作引用圖并對(duì)對(duì)象的引用圖進(jìn) 行分析、通過(guò)將分配時(shí)間與分配路徑與分配對(duì)象的綁定可以直接獲得與泄漏 嫌疑對(duì)象對(duì)應(yīng)的分配路徑、有助于修復(fù)泄漏,易于發(fā)現(xiàn)代碼跟蹤輸入項(xiàng)以及 找到被分配的對(duì)象是如何被使用的、尤其是可以同時(shí)發(fā)現(xiàn)泄漏的對(duì)象以及能 夠確定候選分配路徑,并且該候選分配路徑可以僅僅通過(guò)一次訪問(wèn)堆就可以 實(shí)現(xiàn)。該方法有助于將用戶從瑣碎的中斷和分析中解脫出來(lái),防止系統(tǒng)進(jìn)行 多重堆訪問(wèn)或堆轉(zhuǎn)儲(chǔ),因此縮短了診斷的時(shí)間。此外,本發(fā)明的方法不需要 對(duì)現(xiàn)有的虛擬機(jī)進(jìn)行任何修改、不需要對(duì)內(nèi)部GC機(jī)制進(jìn)行任何修改、不需 要對(duì)事件監(jiān)聽的去分配(de-allocation )、甚至不需要考慮對(duì)象的移動(dòng)。
圖7是采用上述方法的裝置的一個(gè)實(shí)施例。如圖7所示,根據(jù)本發(fā)明的診斷內(nèi)存泄漏的裝置700包括對(duì)象分配跟 蹤器件701,用于跟蹤應(yīng)用程序70S在虛擬機(jī)712上運(yùn)行過(guò)程中的對(duì)象分配, 從而獲耳又對(duì)象的分配路徑和分配時(shí)間;分配路徑記錄裝置702,用于記錄從 對(duì)象分配跟蹤器件701傳送來(lái)的每個(gè)對(duì)象的分配路徑和分配時(shí)間;存儲(chǔ)器 703,用于存儲(chǔ)從分配路徑記錄器件702傳送來(lái)的與對(duì)象相關(guān)的分配路徑和分 配時(shí)間;分配路徑管理器件704,用于管理存儲(chǔ)器中所存儲(chǔ)的數(shù)據(jù),以及為 每個(gè)對(duì)象賦予一個(gè)與一條分配路徑相對(duì)應(yīng)的唯一的id并將這種對(duì)應(yīng)關(guān)系以存 儲(chǔ)在存儲(chǔ)器中;用于應(yīng)用程序的堆709,用于存儲(chǔ)從分配路徑記錄器件702 傳送來(lái)的分配對(duì)象的信息;分配路徑讀取器件705,用于讀取所述堆中分配 對(duì)象的信息,并掃描存儲(chǔ)器中存儲(chǔ)的每個(gè)對(duì)象的id以及對(duì)應(yīng)的分配路徑信息, 以便針對(duì)每條分配路徑整理由它分配的、并且還沒(méi)有被回收的對(duì)象并根據(jù)每 個(gè)對(duì)象的分配時(shí)間計(jì)算該路徑所分配同一類對(duì)象的年齡代數(shù);分配路徑排序 器件706,用于根據(jù)每條路徑分配的、并且存活的對(duì)象的年齡代數(shù)對(duì)分配路 徑進(jìn)行排序;以及診斷報(bào)告器件707,用于對(duì)從分配路徑排序器件傳送來(lái)的 分配路徑的排序數(shù)據(jù)進(jìn)行分析,并將高排序的分配路徑確定為可能存在內(nèi)存 泄漏的分配路徑報(bào)告給用戶進(jìn)行分析。
圖8是采用上述方法的裝置的另一個(gè)實(shí)施例。
如圖8所示,根據(jù)本發(fā)明的診斷內(nèi)存泄漏的裝置800包括對(duì)象分配跟 蹤器件801,用于跟蹤應(yīng)用程序808在虛擬機(jī)812上運(yùn)行過(guò)程中對(duì)象的分配, 從而獲取對(duì)象的分配路徑和分配時(shí)間;分配路徑記錄裝置802,用于在每個(gè) 所分配的對(duì)象上打上包含其分配路徑與分配時(shí)間的對(duì)應(yīng)關(guān)系的標(biāo)簽;用于應(yīng) 用程序的堆809,用于存儲(chǔ)從分配路徑記錄器件802傳送來(lái)分配對(duì)象的信息; 分配路徑讀取器件805,針對(duì)每條分配路徑直接按照標(biāo)簽從所述堆中讀取由 它分配的、并且還沒(méi)有被回收的對(duì)象并根據(jù)每個(gè)對(duì)象的分配時(shí)間計(jì)算該路徑 所分配同一類對(duì)象的年齡代數(shù);分配路徑排序器件806,用于根據(jù)每條路徑 分配的、并且存活的對(duì)象的年齡代數(shù)對(duì)分配路徑進(jìn)行排序;以及診斷報(bào)告器 件807,用于對(duì)從分配路徑排序器件806傳送來(lái)的分配路徑的排序數(shù)據(jù)進(jìn)行 分析,并將高排序的分配路徑確定為可能存在內(nèi)存泄漏的分配路徑報(bào)告給用 戶進(jìn)行分析。
對(duì)于上述診斷內(nèi)存泄漏的裝置700和800,其還可以包括對(duì)象壽命管理 器件710以及810以及動(dòng)態(tài)比特碼器件711以及811。對(duì)象壽命管理器件710以及810用于按照對(duì)象分配時(shí)間來(lái)直接計(jì)算對(duì)象的年齡,避免直接將分配時(shí)
間放入所述堆中。動(dòng)態(tài)比特碼器件711以及811可使用二進(jìn)制代碼注入的方
法獲取分配路徑,替換直接讀取運(yùn)行時(shí)堆棧的內(nèi)容以獲取路徑信息。
本發(fā)明的描述是為了示例說(shuō)明的目的而提供的,而不旨在是徹底無(wú)遺漏 的,或者局限于所公開的實(shí)施例。很多修改和變更對(duì)于本領(lǐng)域的普通技術(shù)人 員將是清楚的。選擇這些實(shí)施例是為了說(shuō)明本發(fā)明的原理及其實(shí)際應(yīng)用,并 且使得本領(lǐng)域的其他普通技術(shù)人員能夠理解本發(fā)明,以便實(shí)現(xiàn)可能適于其他 預(yù)期用途的具有各種修改的各種實(shí)施例。
權(quán)利要求
1.一種診斷內(nèi)存泄露的方法,包括跟蹤應(yīng)用程序在虛擬機(jī)上運(yùn)行過(guò)程中的對(duì)象分配,從而獲取并記錄對(duì)象的分配路徑和分配時(shí)間;以預(yù)定的時(shí)間間隔計(jì)算每一類對(duì)象在其分配路徑的年齡代數(shù);以及將其上具有高年齡代數(shù)對(duì)象的分配路徑確定為可能存在內(nèi)存泄漏的分配路徑,并報(bào)告給用戶以進(jìn)行分析
2. 如權(quán)利要求1所述的診斷內(nèi)存泄露的方法,其中,所述預(yù)定的時(shí)間間 隔是垃圾回收間隔或?qū)?yīng)于特定類型和堆棧的對(duì)象的總量達(dá)到規(guī)定的閾值的 時(shí)間。
3. 如權(quán)利要求1或2所述的診斷內(nèi)存泄露的方法,其中,獲取并記錄對(duì) 象的分配路徑和分配時(shí)間的步驟包括為每個(gè)對(duì)象賦予一個(gè)與分配路徑相對(duì) 應(yīng)的p舉一的id。
4. 如權(quán)利要求3所述的診斷內(nèi)存泄露的方法,其中,以預(yù)定的時(shí)間間隔 計(jì)算每一類對(duì)象在其分配路徑其年齡代數(shù)的步驟包括基于每個(gè)對(duì)象的與分 配該對(duì)象的分配路徑相對(duì)應(yīng)id,確定其每個(gè)對(duì)象所屬的分配路徑,并針對(duì)每 條分配路徑整理由它分配的、并且還沒(méi)有被回收的對(duì)象并根據(jù)每個(gè)對(duì)象的分 配時(shí)間計(jì)算該路徑所分配同一類對(duì)象的年齡代數(shù)。
5. 如權(quán)利要求3所述的診斷內(nèi)存泄露的方法,其中,將其上具有高年齡 代數(shù)對(duì)象的分配路徑確定為可能存在內(nèi)存泄漏的分配路徑的步驟包括根據(jù) 每條路徑分配的、并且存活的同類對(duì)象的年齡代數(shù)對(duì)路徑進(jìn)行排序,以及對(duì) 分配路徑的排序數(shù)據(jù)進(jìn)行分析,并將高排序的分配路徑確定為可能存在內(nèi)存 泄漏的分配路徑報(bào)告給用戶進(jìn)行分析。
6. 如權(quán)利要求5所述的診斷內(nèi)存泄露的方法,其中所述跟蹤應(yīng)用程序在 虛擬機(jī)上運(yùn)行過(guò)程中對(duì)象的分配采用一種數(shù)據(jù)結(jié)構(gòu)來(lái)進(jìn)行,該數(shù)據(jù)結(jié)構(gòu)包含 了對(duì)象所屬類的簽名、對(duì)象計(jì)數(shù)、時(shí)間計(jì)數(shù)以及分配路徑。
7. 如權(quán)利要求6所述的診斷內(nèi)存泄露的方法,其中所述為每個(gè)對(duì)象賦予 一個(gè)與一條分配路徑相對(duì)應(yīng)的唯一的id,包括將每個(gè)對(duì)象的與分配路徑相關(guān) 聯(lián)的波段id以及組id包含在一種標(biāo)簽中并將標(biāo)簽與相應(yīng)的對(duì)象綁定。
8. 如權(quán)利要求7所述的診斷內(nèi)存泄露的方法,其中所述標(biāo)簽中還可以包含關(guān)于對(duì)象的類型、路徑、方法以及被調(diào)用者的信息。
9. 如權(quán)利要求4所述的診斷內(nèi)存泄露的方法,其中所述以預(yù)定的時(shí)間間 隔計(jì)算每一類對(duì)象在其分配路徑其年齡代數(shù)從對(duì)象所屬的分配路徑的最高波段id開始。
10. 如權(quán)利要求4所述的方法,其中還包括在進(jìn)行所述整理之前進(jìn)行至少一次垃圾收集。
11. 一種診斷內(nèi)存泄漏的裝置,包括對(duì)象分配跟蹤器件,跟蹤應(yīng)用程序在虛擬機(jī)上運(yùn)行過(guò)程中的對(duì)象分配, 從而獲取并記錄對(duì)象的分配路徑和分配時(shí)間;分配路徑記錄器件,用于記錄從對(duì)象分配跟蹤器件傳送來(lái)的每個(gè)對(duì)象的 分配3各徑和分配時(shí)間;用于應(yīng)用程序的堆,用于存儲(chǔ)從分配路徑記錄器件傳送來(lái)的路徑分配的 對(duì)象信息;分配路徑讀取器件,用于讀取所述堆中路徑分配的對(duì)象信息,并掃描存 儲(chǔ)器中存儲(chǔ)的每個(gè)對(duì)象的id以及對(duì)應(yīng)的分配路徑信息,以便針對(duì)每條分配路 徑整理由它分配的、并且還沒(méi)有被回收的對(duì)象并根據(jù)每個(gè)對(duì)象的分配時(shí)間計(jì) 算該路徑所分配同一類對(duì)象的年齡代數(shù);分配路徑排序器件,用于根據(jù)每條路徑分配的、并且存活的對(duì)象的年齡 代數(shù)把路徑排序;以及進(jìn)行分析,并將高排序的分配路徑確定為可能存在內(nèi)存泄漏的分配路徑報(bào)告 給用戶以進(jìn)行分析。
12. 如權(quán)利要求11所述的診斷內(nèi)存泄漏的裝置,其中對(duì)象分配跟蹤器件 采用 一種數(shù)據(jù)結(jié)構(gòu)來(lái)進(jìn)行對(duì)象分配的跟蹤,該數(shù)據(jù)結(jié)構(gòu)包含了對(duì)象所述的類 的簽名、對(duì)象計(jì)數(shù)、時(shí)間計(jì)數(shù)以及分配路徑。
13. 如權(quán)利要求11或12所述的診斷內(nèi)存泄露的裝置,其還包括對(duì)象壽 命管理器件用于按照對(duì)象分配時(shí)間來(lái)直接計(jì)算對(duì)象的年齡,避免直接將分配 時(shí)間放入所述堆中。
14. 如權(quán)利要求11所述的診斷內(nèi)存泄露的裝置,其還包括動(dòng)態(tài)調(diào)碼器, 其可使用二進(jìn)制代碼注入的方法獲取分配路徑,替換直接讀取運(yùn)行時(shí)堆棧的 內(nèi)容以獲取路徑信息。
15. —種用于診斷內(nèi)存泄漏的裝置,包括對(duì)象分配跟蹤器件,用于跟蹤應(yīng)用程序在虛擬機(jī)上運(yùn)行過(guò)程中的對(duì)象分配,從而獲取對(duì)象的分配路徑和分配時(shí)間;分配路徑記錄器件,用于在每個(gè)所分配的對(duì)象上打上包含其分配路徑與 分配對(duì)象的對(duì)應(yīng)關(guān)系的標(biāo)簽;用于應(yīng)用程序的堆,用于存儲(chǔ)從分配路徑記錄器件傳送來(lái)的路徑分配的 對(duì)象信息;分配路徑讀取器件,對(duì)每條分配路徑直接按照標(biāo)簽從所述堆中讀取由它 分配的、并且還沒(méi)有被回收的對(duì)象,并根據(jù)每個(gè)對(duì)象的分配時(shí)間計(jì)算該路徑 所分配同一類對(duì)象的年齡代數(shù);分配路徑排序器件,用于根據(jù)每條路徑分配的、并且存活的對(duì)象的年齡 代數(shù)把路徑排序;以及診斷報(bào)告器件,用于對(duì)從分配路徑排序器傳送來(lái)的分配路徑的排序數(shù)據(jù) 進(jìn)行分析,并將高排序的分配路徑確定為可能存在內(nèi)存泄漏的分配路徑報(bào)告 給用戶進(jìn)行分析。
16. 如權(quán)利要求15所述的診斷內(nèi)存泄漏的裝置,其中對(duì)象分配跟蹤器件 采用一種數(shù)據(jù)結(jié)構(gòu)來(lái)進(jìn)行對(duì)象分配的跟蹤,該數(shù)據(jù)結(jié)構(gòu)包含了對(duì)象所述的類 的簽名、對(duì)象計(jì)數(shù)、時(shí)間計(jì)數(shù)以及分配路徑。
17. 如權(quán)利要求15所述的診斷內(nèi)存泄露的裝置,其中所述分配路徑記錄 器件通過(guò)將標(biāo)簽與相應(yīng)的對(duì)象綁定來(lái)記錄與分配對(duì)象相關(guān)的信息。
18. 如權(quán)利要求17所述的診斷內(nèi)存泄露的裝置,其中所述標(biāo)簽中還可以 包含關(guān)于對(duì)象的類型、路徑、方法以及被調(diào)用者的信息。
19. 如權(quán)利要求15-19任意一項(xiàng)所述的診斷內(nèi)存泄露的裝置,其還包括 對(duì)象壽命管理器件用于按照對(duì)象分配時(shí)間來(lái)直接計(jì)算對(duì)象的年齡,避免直接 將分配時(shí)間放入所述對(duì)象標(biāo)簽中。
20. 如權(quán)利要求19所述的診斷內(nèi)存泄露的裝置,其還包括動(dòng)態(tài)變碼器, 其可使用二進(jìn)制代碼注入的方法獲取分配路徑,替換直接讀取運(yùn)行時(shí)堆棧的 內(nèi)容以獲取路徑信息。
全文摘要
一種診斷內(nèi)存泄露的方法和裝置。所述方法包括跟蹤應(yīng)用程序在虛擬機(jī)上運(yùn)行過(guò)程中的對(duì)象分配,從而獲取對(duì)象的分配路徑和分配時(shí)間;記錄每個(gè)對(duì)象的分配路徑和分配時(shí)間;為每個(gè)對(duì)象賦予一個(gè)與一條分配路徑相對(duì)應(yīng)的唯一的ID;基于每個(gè)對(duì)象的與分配該對(duì)象的分配路徑相對(duì)應(yīng)ID,確定其每個(gè)對(duì)象所屬的路徑;針對(duì)每條分配路徑整理由它分配的、并且還沒(méi)有被回收的對(duì)象并根據(jù)這些對(duì)象的分配時(shí)間計(jì)算該路徑所分配同一類對(duì)象的“年齡代數(shù)”;根據(jù)每條路徑分配的、并且存活的同類對(duì)象的年齡代數(shù)對(duì)路徑進(jìn)行排序;以及對(duì)分配路徑的排序數(shù)據(jù)進(jìn)行分析,排序越高的分配路徑,越有可能是引入內(nèi)存泄漏。據(jù)此,可能存在內(nèi)存泄漏的分配路徑被挑選、報(bào)告給用戶進(jìn)行分析。本發(fā)明還涉及一種執(zhí)行上述方法的裝置。
文檔編號(hào)G06F9/50GK101615143SQ200810131740
公開日2009年12月30日 申請(qǐng)日期2008年6月27日 優(yōu)先權(quán)日2008年6月27日
發(fā)明者劉天成, 影 李, 李欣慧, 滕啟明, 瀅 陳 申請(qǐng)人:國(guó)際商業(yè)機(jī)器公司