2013-03-12 42 views
2

我想跟蹤一個大型應用程序當前分配了多少內存。有沒有辦法知道在Linux中傳遞給__free_hook的指針的大小?

我發現我可以安裝周圍的malloc /免費/ realloc的掛鉤,以攔截內存分配來電:

http://man7.org/linux/man-pages/man3/malloc_hook.3.html

所以我要跟蹤是分配的總字節數 - 釋放的總字節數。

現在的問題是,free只需要一個指針而不是一個大小。

可以在我的malloc掛鉤中創建自己的映射或散列映射,跟蹤爲該指針分配了多少內存,但這會導致相當多的開銷。

有沒有什麼辦法(即使它是一個黑客)在免費調用時使用Linux(64位)大小的ptr(使用默認的g ++ malloc)?

+0

可能重複[是否有可能找到分配給指針的內存,而不搜索malloc語句](http://stackoverflow.com/questions/5813078/is-it-possible-to-find-the -memory-allocated-to-the-pointer-without-searching-fo) – Floris 2013-03-13 13:19:47

+0

問題是類似的,但不完全相同。那個人打算用它來計算一個數組在代碼本身中有多久,這個答案中建議避免使用這個數組。在這種情況下,這個問題只是爲了跟蹤總內存。 – 2013-03-13 16:21:46

+0

也許 - 但接受的答案在兩種情況下都是一樣的......「使用malloc_usable_size()」。這使得它至少在我心中是一個「可能的重複」。通過創建鏈接,我們爲遇到一個問題的人提供了看到更多可能答案的機會。 – Floris 2013-03-13 16:32:56

回答

5

Linux手冊malloc_usable_size

malloc_usable_size()返回的字節在 動態分配緩衝器的ptr可用的數目,這可以比 請求的大小的情況下(但保證是至少一樣大,如果 請求成功)。通常,您應該存儲 請求的分配大小,而不是使用此功能。

3

這不是直接回答你的問題,但看到你有興趣在總分配的內存,然後在這裏是解決方案:

我想你會對它返回的結構的uordblks字段感興趣。

注意,這不是一個標準的POSIX功能,但我想這是你所期望的非標準反省這樣的...

+0

當你超過4 GB時,mallinfo不起作用 – 2013-03-12 18:19:17

+0

@JeroenDirks:嗯,這是一個公平點! – 2013-03-12 18:28:46

0

您需要在malloc的安裝鉤子建設指針表緩存所請求塊的大小,然後當您釋放時,搜索malloc'd項的以前數據庫中的指針。

通過這種方式,您將知道當前分配的堆總和是多少(如果這是您的目標),並且將有方便的地方列出仍然保留在內存中的所有「區域」。

1

內存塊的大小通常存儲在指針下方。雖然這是一個黑客(你說我能...),下面的代碼在我的Linux機器上運行:

#include <stdio.h> 
#include <stdlib.h> 

int main(){ 
int *p, n=123; 
p = (int*)malloc(n*sizeof(int)); 
printf("allocated %d bytes for p\n", n*sizeof(int)); 
printf("p[-2] : %d \n", *(p-2)); 
printf("malloc_useable_size(p) : %d\n", malloc_usable_size(p)); 
free(p); 
} 

它產生的輸出是這樣的:

allocated 492 bytes to p 
p[-2] : 513 
malloc_useable_size(p): 504 

注意,大小p [-2]並不完全是492 - 由於內務管理和邊界對齊等原因,還有一些額外的空間用完了。

另請注意 - 這與編譯器gcc一起工作;但g++抱怨指針轉換,並且我沒有宣佈malloc_useable_size()。在看到@ fanl的回答後,我出於好奇而添加了該行。在看到@OliCharlesworth的回答後,我還玩了一下mallinfo的輸出。

您可以更改n的值,並且您會看到事物非常吻合 - 例如,如果您將n(在上面的代碼中)從100增加到119,那麼感興趣的不同變量的值爲如下:

n | p[-2] | usable | uordblks 
----+-------+--------+--------- 
100 417  408  416 
101 417  408  416 
102 417  408  416 
103 433  424  432 
104 433  424  432 
105 433  424  432 
106 433  424  432 
107 449  440  448 
108 449  440  448 
109 449  440  448 
110 449  440  448 
111 465  456  464 
112 465  456  464 
113 465  456  464 
114 465  456  464 
115 481  472  480 
116 481  472  480 
117 481  472  480 
118 481  472  480 
119 497  488  496 

總會有9 usablep[-2]1之間p[-2]uordblks之間,以及不同。 p[-2]方法的優點在於它可以準確地告訴你你的詢問 - 這個指針的大小。其他通話可能實際上告訴你什麼你真想 ...

PS這很可能是對的內存非常大的塊,你需要看的是住在*((long int*)(p)-1)long integer。這給了我靈感的一個不錯的宏:

#define PSIZE(a) (*((long int*)(a)-1)) 

然後你可以找到任何指針的大小與

printf("my pointer size is %ld\n", PSIZE(myPointer)); 

而不必擔心指針的類型。我確認這適用於不同類型的指針,對於塊> 4G。顯然,您可以決定在宏中減1,以便數字與mallinfo()完全一致。

編輯:指針下方存儲的內容的更完整描述在this earlier question的答案之一中給出。這表明我觀察到的「+1」實際上是由於存儲在LSB中的標誌。正確的方法是用〜3結果,清除兩個LSB,然後從結果中減去(long int *)的大小(實際上原來的答案減去2 * sizeof(unsigned long int),但我認爲這是錯):

#define PSIZE(a) ((*((long int*)(a)-1))&~3 - sizeof(long int*)) 

鏈接的答案強烈建議只用這個調試,而不是依賴於它的實際代碼。我感到不得不重複這個警告。

+0

這很大程度上取決於glibc的malloc du jour如何做事......最好跟@fanl的答案。 – vonbrand 2013-03-12 20:28:53

相關問題