[英]Is there a way to know size of a pointer passed to a __free_hook in Linux?
我想跟蹤大型應用程序當前分配的內存量。
我發現我可以在malloc / free / realloc周圍安裝鈎子以攔截內存分配調用:
http://man7.org/linux/man-pages/man3/malloc_hook.3.html
所以我要跟蹤的是分配的總字節數 - 釋放的總字節數。
現在問題是free只接受指針而不是大小。
在我的malloc鈎子中可以創建我自己的map或hashmap,它跟蹤為該指針分配了多少內存,但這會導致相當多的開銷。
有沒有辦法(即使它有點像黑客)在調用free時使用ptr的大小(使用默認的g ++ malloc)獲得Linux(64位)的大小?
linux man malloc_usable_size
malloc_usable_size()返回動態分配的緩沖區ptr中可用的字節數,該緩沖區可能大於請求的大小(但如果請求成功,則保證至少同樣大)。 通常,您應該存儲請求的分配大小,而不是使用此函數。
這不是你問題的直接答案,但看到你對總分配內存感興趣,那么這就是解決方案:
我想你最感興趣的是它返回的struct的uordblks
字段。
請注意,這不是標准的POSIX函數,但我想這就是你對非標准內省的預期......
存儲塊的大小通常存儲在指針的正下方。 雖然這是一個黑客(你說我可以......),但我的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的回答后,我出於好奇而添加了這一行。 在看到mallinfo
的答案之后,我還在mallinfo
的輸出中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
usable
和p[-2]
之間總是有9的差異, p[-2]
和uordblks
之間的差異總是1
。 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()完全一致。
編輯:在此前一個問題的答案中給出了對指針下方存儲內容的更完整描述。 這表明我觀察到的“+1”實際上是由於存儲在LSB中的標志。 正確的方法是將結果與~3一起清除兩個LSB,然后從結果中減去(long int *)的大小(實際上原始答案減去2 * sizeof(unsigned long int)但我認為是錯誤):
#define PSIZE(a) ((*((long int*)(a)-1))&~3 - sizeof(long int*))
鏈接的答案強烈建議僅將其用於調試,而不是將其用於實際代碼。 我不得不重復這一警告。
您需要在malloc中安裝一個鈎子來構建一個緩存所請求塊大小的指針表,然后在釋放時,在上一個malloc項目數據庫中搜索指針。
通過這種方式,您將知道減少當前分配的堆總和(如果這是您的目標),並且將有一個方便的位置來列出仍保留在內存中的堆的所有“區域”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.