我想跟踪大型应用程序当前分配的内存量。
我发现我可以在malloc / free / realloc周围安装钩子以拦截内存分配调用:
http://man7.org/linux/man-pages/man3/malloc_hook.3.html
所以我要跟踪的是分配的总字节数 - 释放的总字节数。
现在的问题是free只接受指针而不是大小。
In可以在我的malloc钩子中创建我自己的map或hashmap,它跟踪为该指针分配了多少内存,但这会导致相当多的开销。
有没有办法(即使它有点像黑客)在调用free时使用ptr大小的Linux(64位)(使用默认的g ++ malloc)?
答案 0 :(得分:5)
linux man malloc_usable_size
malloc_usable_size()返回可用的字节数 动态分配的缓冲区ptr,可能大于 请求的大小(但保证至少与大小一样大 请求成功)。通常,您应该存储 请求分配大小而不是使用此功能。
答案 1 :(得分:3)
这不是你问题的直接答案,但看到你对总分配内存感兴趣,那么这就是解决方案:
我认为你最感兴趣的是它返回的结构的uordblks
字段。
请注意,这不是标准的POSIX功能,但我想这就是你对这种非标准内省所期望的......
答案 2 :(得分: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
usable
和p[-2]
之间以及1
和p[-2]
之间的uordblks
之间始终存在9的差异。 p[-2]
方法的优势在于它可以准确地告诉您要求的内容 - 此指针的大小。其他电话实际上可能会告诉您真正想要的内容 ...
PS很可能对于非常大的内存块,您需要查看long integer
生成的*((long int*)(p)-1)
。这给了我一个漂亮的宏的灵感:
#define PSIZE(a) (*((long int*)(a)-1))
然后你可以用
找出任何指针的大小printf("my pointer size is %ld\n", PSIZE(myPointer));
无需担心指针的类型。我确认这适用于不同类型的指针,对于块&gt; 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*))
链接的答案强烈建议仅将其用于调试,而不是将其用于实际代码。我不得不重复这个警告。
答案 3 :(得分:0)
你需要在malloc中安装一个钩子来构建一个缓存所请求块大小的指针表,然后当你空闲时,在上一个malloc项目数据库中搜索指针。
通过这种方式,您将知道减少当前分配的堆总和(如果这是您的目标),并且将有一个方便的位置来列出仍在内存中的堆的所有“区域”。