日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

DHAT:动态堆分析工具

發(fā)布時間:2025/3/15 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DHAT:动态堆分析工具 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

10.1。概觀10.2。了解DHAT的輸出
10.2.1。解釋max-live,tot-alloc和deaths字段10.2.2。解釋比例字段10.2.3。解釋“通過偏移量進行聚合訪問計數”數據
10.3。DHAT命令行選項

要使用此工具,必須--tool=exp-dhat在Valgrind命令行上指定?。

10.1。概觀

DHAT是一個用于檢查程序如何使用其堆分配的工具。

它跟蹤分配的塊,并檢查每個內存訪問以查找哪個塊(如果有的話)。每個分配點(分配堆棧)收集和顯示以下數據:

  • 總分配(字節(jié)數和塊數)

  • 最大實際體積(字節(jié)數和塊數)

  • 平均塊壽命(分配和釋放之間的指令數)

  • 塊中每個字節(jié)的平均讀寫次數(“訪問率”)

  • 對于始終分配只有一個大小的塊的分配點,大小為4096字節(jié)或更少:計數表示訪問塊內每個字節(jié)偏移的頻率。

使用這些統(tǒng)計信息可以識別具有以下特征的分配點:

  • 潛在的過程生命周期泄漏:由點分配的塊剛剛累積,僅在運行結束時釋放。

  • 過多的營業(yè)額:即使沒有持續(xù)很長時間,咀嚼了很多堆的點數

  • 過度瞬態(tài):分配非常短暫的塊的點

  • 無用或未充分使用的分配:分配但未完全填充或填寫但未隨后讀取的塊。

  • 具有低效布局的區(qū)域 - 從未訪問的區(qū)域,或者散布在整個塊中的熱場。

與Massif堆分析器一樣,DHAT通過計數指令來測量程序進度,因此將所有年齡/時間相關數字作為指令計數。這首先聽起來有點奇怪,但是如果使用CPU時間,則使得運行可重復的方式是不可能的。

10.2。了解DHAT的輸出

DHAT提供了大量有關動態(tài)堆使用的有用信息。大多數使用它的藝術是解釋結果的數字。這是通過一組示例來說明的。

10.2.1。解釋max-live,tot-alloc和deaths字段

10.2.1.1。一個簡單的例子

========摘要統(tǒng)計========guest_insns:1,045,339,534[...]最大活動:63,490,984個塊tot-alloc:29,520塊中的1,904,700(平均尺寸64.52)死亡人數:29,520人,平均22,227,424人比例:6.37 rd,1.14 wr(12,141,526 b-read,2,174,460 b-written)在0x4C275B8:malloc(vg_replace_malloc.c:236)通過0x40350E:tcc_malloc(tinycc.c:6712)通過0x404580:tok_alloc_new(tinycc.c:7151)by 0x40870A:next_nomacro1(tinycc.c:9305)

在整個程序中,這個堆棧(分配點)共分配了29,520個塊,總共包含1,904,700個字節(jié)。通過查看max-live數據,我們看到沒有多少塊同時生效,但是在高峰期,984個塊中有63,490個分配的字節(jié)。這告訴我們,該程序正在穩(wěn)定地釋放這樣的塊,而不是掛在所有的塊上,直到結束并釋放它們。

死亡條目告訴我們,這個堆棧分配的29,520個塊在程序運行期間死了(被釋放)。由于29,520也是總共分配的塊的數量,這告訴我們所有分配的塊在程序結束時被釋放。

它也告訴我們,平均死亡年齡為22,227,424個指示。從總結統(tǒng)計,我們看到,該計劃運行了1,045,339,534個指令,因此平均死亡年齡約為程序總運行時間的2%。

10.2.1.2。潛在的過程壽命泄漏示例

下一個示例(來自與上述不同的程序)顯示潛在的進程生命周期泄漏。當程序繼續(xù)分配數據時,會發(fā)生進程生命周期泄漏,但只能在退出之前釋放數據。因此,程序堆的大小不斷增加,但是Memcheck報告沒有泄漏,因為程序在退出時已經釋放了一切。這對于長時間運行的程序尤其危險。

========摘要統(tǒng)計========guest_insns:418,901,537[...]max-live:25412塊中的32,512tot-alloc:25412塊中的32,512(平均尺寸128.00)死亡人數:254人,平均年齡300,467,389人比例:0.26 rd,0.20 wr(8,756 b-read,6,604 b-written)在0x4C275B8:malloc(vg_replace_malloc.c:236)通過0x4C27632:realloc(vg_replace_malloc.c:525)by 0x56FF41D:QtFontStyle :: pixelSize(unsigned short,bool)(qfontdatabase.cpp:269)by 0x5700D69:loadFontConfig()(qfontdatabase_x11.cpp:1146)

有兩個跡象表明這可能是一個生命周期的泄漏。首先,max-live和tot-alloc數字是相同的。可能發(fā)生的唯一方法是如果這些塊都被分配,然后全部被釋放。

其次,平均死亡人數(3億人)是總計劃生命周期的71%(4.1億美元),因此這不是一個暫時的無分配飆升 - 而是分散在大部分整個運行。一個解釋是,大概地,所有254個塊都在上半場被分配到下一半,然后在退出之前釋放。

10.2.2。解釋比例字段

10.2.2.1。相當無害的分配點記錄

最大活動:59,398個808個塊tot-alloc:24,240塊中的1,481,940(平均61.13)死亡人數:24,240人,平均年齡34,611,026人比例:2.13 rd,0.91 wr(3,166,650 b-read,1,358,820 b-written)在0x4C275B8:malloc(vg_replace_malloc.c:236)通過0x40350E:tcc_malloc(tinycc.c:6712)通過0x404580:tok_alloc_new(tinycc.c:7151)通過0x4046C4:tok_alloc(tinycc.c:7190)

比例字段告訴我們,在塊被釋放之前,這里分配的塊中的每個字節(jié)讀取平均值為2.13倍。鑒于這些區(qū)塊的平均死亡年齡為34,611,026,每塊大約每1500個指令讀取一次。所以從這個角度來看,這些區(qū)別并不“工作”。

更有趣的是寫入比率:每個字節(jié)平均寫入0.91次。這告訴我們,分配的塊的一些部分永遠不會被寫入,平均至少有9%。要完全初始化塊將需要寫入每個字節(jié)至少一次,這將使寫入比為1.0。一些塊區(qū)明顯未被使用的事實可能指向數據對齊孔或其他布局低效。

那么,至少所有的區(qū)塊都被釋放(24,240個分配,24,240個死亡)。

如果所有的塊都是相同的大小,那么DHAT也會通過塊偏移來顯示訪問計數,所以我們可以看到這些未使用的區(qū)域在哪里。但是,情況并非如此:塊的大小不一樣,所以DHAT無法進行這樣的分析。我們可以看到它們必須具有不同的大小,因為平均塊大小(61.13)不是整數。

10.2.2.2。一個更可疑的例子

max-live:180,224在22個街區(qū)tot-alloc:22,2塊中的180,224(平均尺寸8192.00)死亡:無(這些區(qū)塊都沒有被釋放)比例:0.00 rd,0.00 wr(0 b-read,0 b-written)在0x4C275B8:malloc(vg_replace_malloc.c:236)通過0x40350E:tcc_malloc(tinycc.c:6712)0x40369C:__sym_malloc(tinycc.c:6787)通過0x403711:sym_malloc(tinycc.c:6805)

這里,讀取和寫入訪問率都為零。因此,這一點是分配從未使用的塊,既不讀也不寫。事實上,他們也沒有被釋放(“死亡:無”),只是泄漏了。所以,這里是180k的完全無用的分配,可以刪除。

與Memcheck重新運行確實報告了同樣的泄漏。什么DHAT可以告訴我們,Memcheck不能,不僅是塊泄漏,它們也從未被使用過。

10.2.2.3。另一個可疑的例子

這里是一個分配塊,寫入但從不讀取的地方。我們從零讀取訪問比率立即看到這一點。他們確實得到釋放:

max-live:54個3個塊tot-alloc:1,020塊(平均尺寸18.00)死亡人數:90人,平均年齡34,558,236人比例:0.00 rd,1.11 wr(0 b-read,1,800 b-written)在0x4C275B8:malloc(vg_replace_malloc.c:236)通過0x40350E:tcc_malloc(tinycc.c:6712)通過0x4035BD:tcc_strdup(tinycc.c:6750)通過0x41FEBB:tcc_add_sysinclude_path(tinycc.c:20931)

在前面的兩個示例中,很容易看到從不寫入或從不讀取的塊或兩者的某種組合。不幸的是,在C ++代碼中,情況不太清楚。這是因為一個對象的構造函數將寫入底層的塊,并且它的析構函數將從它讀取。因此,即使該對象一旦構造,該塊的讀取和寫入比率將不為零,也不會被使用,但只能最終被破壞。

真的,我們想要的只是在對象的構造結束和其破壞開始之間測量內存訪問。不幸的是,我不知道確定何時進行這些轉換的可靠方法。

10.2.3。解釋“通過偏移量進行聚合訪問計數”數據

對于總是分配相同大小的塊,分配4096字節(jié)或更小的塊的分配點,DHAT計數每個偏移量的訪問,例如:

max-live:317,408,5,668個塊tot-alloc:317,408,5,668塊(平均尺寸56.00)死亡人數:5,668人,平均622,890,597人比例:1.03 rd,1.28 wr(327,642 b-read,408,172 b-written)在0x4C275B8:malloc(vg_replace_malloc.c:236)通過0x5440C16:QDesignerPropertySheetPrivate :: ensureInfo(qhash.h:515)通過0x544350B:QDesignerPropertySheet :: setVisible(qdesigner_propertysh ...)通過0x5446232:QDesignerPropertySheet :: QDesignerPropertySheet(qdesigne ...)按偏移量進行聚合訪問計數:[0] 28782 28782 28782 28782 28782 28782 28782 28782[8] 20638 20638 20638 20638 0 0 0 0 [16] 22738 22738 22738 22738 22738 22738 22738 22738[24] 6013 6013 6013 6013 6013 6013 6013 6013 [32] 18883 18883 18883 37422 0 0 0 0[36] 5668 11915 5668 5668 11336 11336 11336 11336 [48] 6166 6166 6166 6166 0 0 0 0

對于在64位平臺上運行的C ++代碼,這是相當典型的。在這里,我們對5668個塊的訪問統(tǒng)計信息進行了匯總,大小為56字節(jié)。每個字節(jié)至少被訪問5668次,除了偏移量12--15,36-39和52-55之外。這些可能是對準孔。

數字的仔細詮釋揭示了有用的信息。以N對齊偏移開始的N個連續(xù)相同數字的組,對于N為2,4或8,可能在該點處的結構中指示N字節(jié)對象。例如,該對象的前32個字節(jié)可能具有布局

[0] 64位類型[8] 32位類型[12] 32位定位孔[16] 64位類型[24] 64位類型

作為反例,還清楚的是,無論在偏移量32處,它不是32位值。那是因為最后一個組(37422)與前三個(18883 18883 18883)不一樣。

這個例子引導一個人查詢(通過讀取源代碼)12-15和52-55的零是否是對齊孔,以及48--51是否確實是一個32位類型。如果是這樣,可能會將位置在48-51之間的位置替換為12--15,這樣可以將對象大小從56個字節(jié)縮小到48個字節(jié)。

請記住,以上推論只是“可能”。這是因為它們基于動態(tài)數據,而不是對對象布局的靜態(tài)分析。例如,零可能不是對齊孔,而只是結構的一部分,這些部分根本不用于此特定的運行。經驗表明,不太可能是這種情況,但可能會發(fā)生。

10.3。DHAT命令行選項

DHAT特定的命令行選項有:

--show-top-n=<number> [default: 10]

在運行結束時,DHAT根據某個度量對累積的分配點進行排序,并顯示最高的得分條目。?--show-top-n?控制顯示的條目數。默認值為10是相當小的。對于現實的應用,您可能需要將其設置得更高,至少有幾百個。

--sort-by=<string> [default: max-bytes-live]

在運行結束時,DHAT根據某個度量對累積的分配點進行排序,并顯示最高的得分條目。?--sort-by?選擇用于排序的度量:

max-bytes-live?最大活動字節(jié)[默認]

tot-bytes-allocd?字節(jié)總共分配(營業(yè)額)

max-blocks-live?最大活動塊

tot-blocks-allocd?分配總數(營業(yè)額)

這樣可以控制顯示分配點的順序。您可以選擇查看具有最多實時字節(jié)數或最高總字節(jié)周轉量,或最高數量的實時數據塊或最高總數據塊周轉量的分配點。這些給程序行為有用的不同圖片。例如,通過最大活動塊進行排序往往會顯示創(chuàng)建大量小對象的分配點。

需要注意的一個重要的一點是每個分配堆棧都是單獨的分配點。因為默認情況下堆棧有12個幀,所以這往往會在多個分配點上傳播數據。你可能想使用標記--num-callers = 4或一些這么小的數字來減少擴展。

總結

以上是生活随笔為你收集整理的DHAT:动态堆分析工具的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。