Linux
/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() 作為分配記憶體的一種方式?
可以通過足夠大的 來創建無名區域
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 $
我想您可以使用
gdb
malloc 跟踪器或其他方法來解決mmap
在您的記憶體密集型程序中對特定程式碼的特定備份…