Linux

/proc/pid/smaps 中的無名條目是什麼?

  • May 4, 2017

我試圖弄清楚程序中什麼會佔用大量記憶體,因此我嘗試閱讀/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() 作為分配記憶體的一種方式?

可以通過足夠大的 來創建無名區域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在您的記憶體密集型程序中對特定程式碼的特定備份…

引用自:https://unix.stackexchange.com/questions/363079