在他对问题的回答中Linux 上 proc 文件系统的更新频率是多少?,乔纳森·本·亚伯拉罕表示/proc/.../statm
只要您阅读它,它就是最新的,因为直接阅读它会触发内核回调。
这些内核回调读取的数据怎么样?这是否总是正确的,或者在 malloc/new 请求的内存和内核使测量可供使用之间是否存在一些时间滞后/proc/.../statm
?
我正在尝试找到一种测量通过malloc
或分配的对象的当前大小的方法new
。
运行一个分配一些数据的小型测试程序,无论是/proc/.../statm
调用还是调用sbrk()
似乎都不会立即与进程分配的内存量相关。
难道就没有办法获得准确的信息吗?
程序分配 64KB 和 128KB 块
$ ./a.out
MALLOC TEST. Size = 131072
0 ALLOC: HEAP SIZE: 0 MEMORY USAGE (statm): 1083 201 173 2 0 341 0
1 ALLOC: HEAP SIZE: 135168 MEMORY USAGE (statm): 1083 211 182 2 0 341 0
2 ALLOC: HEAP SIZE: 135168 MEMORY USAGE (statm): 1116 215 185 2 0 374 0
3 ALLOC: HEAP SIZE: 135168 MEMORY USAGE (statm): 1149 216 185 2 0 407 0
4 ALLOC: HEAP SIZE: 135168 MEMORY USAGE (statm): 1182 217 185 2 0 440 0
5 ALLOC: HEAP SIZE: 135168 MEMORY USAGE (statm): 1215 218 185 2 0 473 0
6 ALLOC: HEAP SIZE: 135168 MEMORY USAGE (statm): 1248 219 185 2 0 506 0
7 ALLOC: HEAP SIZE: 135168 MEMORY USAGE (statm): 1281 220 185 2 0 539 0
8 ALLOC: HEAP SIZE: 135168 MEMORY USAGE (statm): 1314 221 185 2 0 572 0
9 ALLOC: HEAP SIZE: 135168 MEMORY USAGE (statm): 1347 222 185 2 0 605 0
$ ./a.out
MALLOC TEST. Size = 65536
0 ALLOC: HEAP SIZE: 0 MEMORY USAGE (statm): 1067 201 174 2 0 325 0
1 ALLOC: HEAP SIZE: 0 MEMORY USAGE (statm): 1067 211 182 2 0 325 0
2 ALLOC: HEAP SIZE: 0 MEMORY USAGE (statm): 1067 215 185 2 0 325 0
3 ALLOC: HEAP SIZE: 196608 MEMORY USAGE (statm): 1115 216 185 2 0 373 0
4 ALLOC: HEAP SIZE: 196608 MEMORY USAGE (statm): 1115 217 185 2 0 373 0
5 ALLOC: HEAP SIZE: 196608 MEMORY USAGE (statm): 1115 218 185 2 0 373 0
6 ALLOC: HEAP SIZE: 393216 MEMORY USAGE (statm): 1163 219 185 2 0 421 0
7 ALLOC: HEAP SIZE: 393216 MEMORY USAGE (statm): 1163 220 185 2 0 421 0
8 ALLOC: HEAP SIZE: 393216 MEMORY USAGE (statm): 1163 221 185 2 0 421 0
9 ALLOC: HEAP SIZE: 589824 MEMORY USAGE (statm): 1211 222 185 2 0 469 0
测试程序
class CfgProfileList
{
public:
bool obtainSystemProfileList();
void leakTest();
void leakObjTest();
std::set<std::string> mProfileList;
private:
char dummy[1024 * 1024]; // use up some space
};
class ComUtil
{
public:
static void printMemoryUsage();
private:
static unsigned int mHeapOrigin;
};
/* static */
unsigned int ComUtil::mHeapOrigin = 0;
// Print current process memory utilization
/* static */ void
ComUtil::printMemoryUsage()
{
unsigned int pHeap = (unsigned int)sbrk(0);
if (mHeapOrigin == 0)
mHeapOrigin = pHeap;
printf("HEAP SIZE: %u\t", pHeap - mHeapOrigin);
char fname[256], line[256];
sprintf(fname, "/proc/%d/statm", getpid());
FILE *pFile = fopen(fname, "r");
if (!pFile)
return;
fgets(line, 255, pFile);
fclose(pFile);
printf("MEMORY USAGE (statm): %s", line);
}
void
CfgProfileList::leakTest()
{
char *pointerList[50];
int n = 10;
int sleep = 1;
int size = 64 * 1024;
printf("MALLOC TEST. Size = %d\n", size);
for (int i = 0; i < n; i++)
{
pointerList[i] = (char *)malloc(size);
printf("%d ALLOC: ", i);
ComUtil::printMemoryUsage();
usleep(sleep);
}
}
int
main(int argc, char **argv)
{
CfgProfileList pl;
pl.leakTest();
}
答案1
你的痕迹对我来说似乎基本上没问题......(记住有一个初始堆,你的代码无法测量。)
MALLOC TEST. Size = 131072
这里您要分配 128KB 块,因此分配器可能不会使用sbrk()
, 但mmap()
。
0 ALLOC: HEAP SIZE: 0 MEMORY USAGE (statm): 1083 201 173 2 0 341 0
1 ALLOC: HEAP SIZE: 135168 MEMORY USAGE (statm): 1083 211 182 2 0 341 0
这很奇怪,你的堆增加了,但你的程序页面却没有增加。
2 ALLOC: HEAP SIZE: 135168 MEMORY USAGE (statm): 1116 215 185 2 0 374 0
3 ALLOC: HEAP SIZE: 135168 MEMORY USAGE (statm): 1149 216 185 2 0 407 0
4 ALLOC: HEAP SIZE: 135168 MEMORY USAGE (statm): 1182 217 185 2 0 440 0
5 ALLOC: HEAP SIZE: 135168 MEMORY USAGE (statm): 1215 218 185 2 0 473 0
6 ALLOC: HEAP SIZE: 135168 MEMORY USAGE (statm): 1248 219 185 2 0 506 0
7 ALLOC: HEAP SIZE: 135168 MEMORY USAGE (statm): 1281 220 185 2 0 539 0
8 ALLOC: HEAP SIZE: 135168 MEMORY USAGE (statm): 1314 221 185 2 0 572 0
9 ALLOC: HEAP SIZE: 135168 MEMORY USAGE (statm): 1347 222 185 2 0 605 0
这里每个分配都会占用堆外额外的 33 页或 132KB,所以一切正常。
MALLOC TEST. Size = 65536
0 ALLOC: HEAP SIZE: 0 MEMORY USAGE (statm): 1067 201 174 2 0 325 0
1 ALLOC: HEAP SIZE: 0 MEMORY USAGE (statm): 1067 211 182 2 0 325 0
2 ALLOC: HEAP SIZE: 0 MEMORY USAGE (statm): 1067 215 185 2 0 325 0
这里您的分配适合初始堆。
3 ALLOC: HEAP SIZE: 196608 MEMORY USAGE (statm): 1115 216 185 2 0 373 0
4 ALLOC: HEAP SIZE: 196608 MEMORY USAGE (statm): 1115 217 185 2 0 373 0
5 ALLOC: HEAP SIZE: 196608 MEMORY USAGE (statm): 1115 218 185 2 0 373 0
堆增加了 192KB,与分配的页面匹配,并且适合三个分配。
6 ALLOC: HEAP SIZE: 393216 MEMORY USAGE (statm): 1163 219 185 2 0 421 0
7 ALLOC: HEAP SIZE: 393216 MEMORY USAGE (statm): 1163 220 185 2 0 421 0
8 ALLOC: HEAP SIZE: 393216 MEMORY USAGE (statm): 1163 221 185 2 0 421 0
又一样...
9 ALLOC: HEAP SIZE: 589824 MEMORY USAGE (statm): 1211 222 185 2 0 469 0
... 然后再次。
一起跑步strace -e brk,mmap
将有助于理解事物。sbrk()
所提供的信息/proc
准确无误。