内核中进程内存测量更新的速度/频率如何?

内核中进程内存测量更新的速度/频率如何?

在他对问题的回答中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准确无误。

相关内容