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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

堆状态分析的利器——gperftools的Heap Profiler

發布時間:2023/11/27 生活经验 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 堆状态分析的利器——gperftools的Heap Profiler 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? ? 在《內存泄漏分析的利器——gperftools的Heap Checker》一文中,我們介紹了如何使用gperftools分析內存泄漏。本文將介紹其另一個強大的工具——Heap Profiler去分析堆的變化過程。(轉載請指明出于breaksoftware的csdn博客)

? ? ? ? 我們使用類似于《堆狀態分析的利器——valgraind的DHAT》中的測試代碼作為例子。為了讓Heap Profiler產生多份快照文件,我將申請的內存放大了很多

#include <stdlib.h>void* create(unsigned int size) {return malloc(size);
}void create_destory(unsigned int size) {void *p = create(size);free(p);
}int main(void) {const int loop = 4;char* a[loop];unsigned int mega = 1024 * 1024;for (int i = 0; i < loop; i++) {const unsigned int create_size = 1024 * mega;create(create_size);const unsigned int malloc_size = 1024 * mega;a[i] = (char*)malloc(malloc_size);const unsigned int create_destory_size = mega;create_destory(create_destory_size);}for (int i = 0; i < loop; i++) {free(a[i]);}return 0;
}

? ? ? ? 第19行每次申請1G的空間,且在整個程序周期中,都不會釋放。

? ? ? ? 第22行每次申請1G的空間,每個空間都將在第29行釋放掉。

? ? ? ? 第25行調用的create_destory方法,每次申請1M的空間,每次申請完就釋放掉。

? ? ? ? 為了方便起見,我們還是要鏈接tcmalloc庫,并開啟調試信息

g++ heap_profiler.cpp -ltcmalloc -g -o heap_profiler

? ? ? ? 編譯完后,使用如下指令開始分析。其中HEAPPROFILE表示的“生成快照文件的目錄格式”。

HEAPPROFILE=/tmp/profile /home/fangliang/gperftools_test/heap_profiler/heap_profiler

? ? ? ? 會得到輸出結果

Starting tracking the heap
Dumping heap profile to /tmp/profile.0001.heap (1024 MB allocated cumulatively, 1024 MB currently in use)
Dumping heap profile to /tmp/profile.0002.heap (2048 MB allocated cumulatively, 2048 MB currently in use)
Dumping heap profile to /tmp/profile.0003.heap (3073 MB allocated cumulatively, 3072 MB currently in use)
Dumping heap profile to /tmp/profile.0004.heap (4097 MB allocated cumulatively, 4096 MB currently in use)
Dumping heap profile to /tmp/profile.0005.heap (5122 MB allocated cumulatively, 5120 MB currently in use)
Dumping heap profile to /tmp/profile.0006.heap (6146 MB allocated cumulatively, 6144 MB currently in use)
Dumping heap profile to /tmp/profile.0007.heap (7171 MB allocated cumulatively, 7168 MB currently in use)
Dumping heap profile to /tmp/profile.0008.heap (8195 MB allocated cumulatively, 8192 MB currently in use)
Dumping heap profile to /tmp/profile.0009.heap (Exiting, 4096 MB in use)

? ? ? ? 第2到9行顯示,每個快照都會增長1G的內存申請。第10行顯示,釋放了4G的內存,最終還有4G的內存沒有被釋放。這個分析結果和代碼的邏輯是一致的:

? ? ? ? 第19行和第22行每次都申請1G空間,一共執行了4次,故8G的在用內存使用量。

? ? ? ? 第25行每次申請并釋放了1M,故不會造成內存增長。

? ? ? ? 第29行每次釋放1G的空間,共執行4次,釋放了4G空間。最終有4G的內存泄漏。

? ? ? ? 我們先看下第一個快照的狀態

pprof --text heap_profiler /tmp/profile.0001.heap

? ? ? ? 此時我們使用的文本輸出方式(--text)

Using local file heap_profiler.
Using local file /tmp/profile.0001.heap.
Total: 1024.0 MB1024.0 100.0% 100.0%   1024.0 100.0% create0.0   0.0% 100.0%   1024.0 100.0% __libc_start_main0.0   0.0% 100.0%   1024.0 100.0% _start0.0   0.0% 100.0%   1024.0 100.0% main

? ? ? ? 第4到7行是調用堆棧,這段顯示create方法申請了1G的空間,且該空間還是可用狀態。

? ? ? ? 再查看快照2

pprof --text heap_profiler /tmp/profile.0002.heap 

? ? ? ? 其結果顯示main函數和create函數各申請了1G的空間(第4~5行第1列),各占總未釋放內存(2G)的50%(第4~5行第2列)。main函數中調用了create方法(第4~5行第3,4,5列顯示出main中直接調用了create,因為main函數中直接和間接申請了2G的空間,其中1G是直接申請的)

Using local file heap_profiler.
Using local file /tmp/profile.0002.heap.
Total: 2048.0 MB1024.0  50.0%  50.0%   1024.0  50.0% create1024.0  50.0% 100.0%   2048.0 100.0% main0.0   0.0% 100.0%   2048.0 100.0% __libc_start_main0.0   0.0% 100.0%   2048.0 100.0% _start

? ? ? ? 為了更方便解讀這組信息,我們使用圖形顯示命令

pprof --gv heap_profiler /tmp/profile.0002.heap 

? ? ? ? 顯示結果如下

? ? ? ? 上圖中,main下面“1024.0(50.0%)”意思是main函數直接申請了1024M尚未釋放的空間,占總未釋放空間的50%。再下面一行“of 2048.0 (100.0%)”意思是main函數直接或者間接申請了2048M尚未釋放的空間(這意味著它申請并釋放了的空間不在該統計內)。create中的信息解讀是類似的。

? ? ? ? 如果只是單純的看一個快照點,是比較難以發現問題。我們需要對比兩個快照,比如我們對比1號和2號快照,看看1G內存的增長是什么導致的

pprof --gv heap_profiler --base=/tmp/profile.0001.heap  /tmp/profile.0002.heap 

? ? ? ? 可以發現,快照1和快照2的變化是:main函數自身申請了1G的空間。

? ? ? ? 我們再對比下8和9號快照

pprof --gv heap_profiler --base=/tmp/profile.0008.heap  /tmp/profile.0009.heap 

? ? ? ? 上面顯示:main函數內部釋放了4G的空間(出現了負值)。這個就是第29行代碼的執行結果,分析和代碼邏輯一致。

? ? ? ? 最后我們再看下最后一片快照

pprof --gv heap_profiler /tmp/profile.0009.heap

? ? ? ? create函數導致的4G內存泄漏就一目了然了。

? ? ? ? 最后提一句,如果項目不能鏈接tcmalloc,則可以使用如下的指令去獲取快照

LD_PRELOAD="/usr/local/lib/libtcmalloc.so" HEAPPROFILE=/tmp/profile /home/fangliang/gperftools_test/heap_profiler/heap_profiler

?

總結

以上是生活随笔為你收集整理的堆状态分析的利器——gperftools的Heap Profiler的全部內容,希望文章能夠幫你解決所遇到的問題。

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