/proc/pid/smaps 中的无名条目是什么?

/proc/pid/smaps 中的无名条目是什么?

我试图找出进程中什么消耗了大量内存,因此我尝试阅读/proc/pid/smaps(其中 pid 是进程的 pid)。

令我困惑的是,有些条目没有名字。例如:

4805d000-4805e000 rwxp 0001d000 00:0b 19674210   /lib/ld-2.6.so
Size:                  4 kB
Rss:                   4 kB
Pss:                   4 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         4 kB
Referenced:            4 kB
Swap:                  0 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
4805e000-4805f000 ---p 00000000 00:00 0 
Size:                  4 kB
Rss:                   0 kB
Pss:                   0 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         0 kB
Referenced:            0 kB
Swap:                  0 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
4805f000-4885e000 rwxp 00000000 00:00 0 
Size:               8188 kB
Rss:                8188 kB
Pss:                8188 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:      8188 kB
Referenced:         8188 kB
Swap:                  0 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB

上面,第一个条目有 name /lib/ld-2.6.so,但第二个和第三个条目没有任何名称。那么,那些无名条目是什么?如何找出哪个库创建了它们?


出于好奇,还有什么(除了 valgrind 之外)可以尝试找出程序中什么消耗了内存吗?


在深入研究内核代码后,我发现这些条目确实无法映射到任何文件(fs/proc/task_mmu.c)。但问题仍然存在:它们是什么? mmap() 作为分配内存的一种方式?

答案1

可以通过足够大的创建无名区域malloc

#include <sys/types.h>    
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
    int *ip;
    char *before, *after;

    asprintf(&before, "cat /proc/%d/smaps > before", getpid());
    asprintf(&after, "cat /proc/%d/smaps > after", getpid());

    system(before);

    ip = malloc(9999999);
    if (!ip) abort();

    system(after);
    return 0;
}

如图所示

$ CFLAGS=-g make ilikebigmallocs
cc -g    ilikebigmallocs.c   -o ilikebigmallocs
$ ./ilikebigmallocs 
$ diff before after
64a65,80
> 7f97425ac000-7f9742f36000 rw-p 00000000 00:00 0 
> Size:               9768 kB
> Rss:                   4 kB
...

所以至少你的一些区域可能是由malloc或类似的东西创建的(在幕后称为mmap)。strace(或sysdig) 可以记录这些:

$ strace -e trace=memory -o blah ./ilikebigmallocs
$ awk '/^mmap/{print $NF}' blah
0x7fc6193b1000
0x7fc6193a6000
...
$ grep 7fc6193b1000 after
7fc6193b1000-7fc6193b2000 rw-p 00000000 00:00 0 
$ 

我想您可以使用gdbmalloc 跟踪器或其他方法来解决mmap内存饥饿进程中特定代码的特定备份...

相关内容