proc文件系统之内存使用

Linux内存使用分析

Linux的proc文件系统提供了很多进程内存使用情况的信息,详细请参考[1][2]

/proc/pid/maps文件

The /proc/PID/maps file containing the currently mapped memory regions and their access permissions.

maps文件的格式为:

1
2
3
4
5
6
7
8
9
10
11
12
13
address perms offset dev inode pathname
08048000-08049000 r-xp 00000000 03:00 8312 /opt/test
08049000-0804a000 rw-p 00001000 03:00 8312 /opt/test
0804a000-0806b000 rw-p 00000000 00:00 0 [heap]
a7cb1000-a7cb2000 ---p 00000000 00:00 0
a7cb2000-a7eb2000 rw-p 00000000 00:00 0
a7eb2000-a7eb3000 ---p 00000000 00:00 0
a7eb3000-a7ed5000 rw-p 00000000 00:00 0
......
aff35000-aff4a000 rw-p 00000000 00:00 0 [stack]
ffffb000-ffffd000 r-xp 00000000 00:00 0 [vdso]
ffffe000-fffff000 r-xp 00000000 00:00 0 [vsyscall]

  • address: the starting and ending address of the region in the process’s address space
  • perms: 访问权限,This describes how pages in the region can be accessed.If the process attempts to access memory in a way that is not permitted, a segmentation fault is generated. Permissions can be changed using the mprotect system call.
    • r = read
    • w = write
    • x = execute
    • s = shared
    • p = private (copy on write)
  • offset: 偏移量,如果这段内存是从文件里映射过来的,则偏移量为这段内容在文件中的偏移量,否则为0。
  • dev: is the device (major:minor), If the region was mapped from a file, this is the major and minor device number (in hex) where the file lives.
  • inode: If the region was mapped from a file, this is the file number.0 indicates that no inode is associated
    with the memory region, as the case would be with BSS (uninitialized data).
  • pathname: The name associated file for this mapping. This field is blank for anonymous mapped regions. There are also special regions with names like:
    • [heap]: the heap of the process
    • [stack]: the stack of the main process
    • [vdso]: the virtual dynamic shared object. It’s used by system calls to switch to kernel mode.
    • [vsyscall]: system calls
    • 如果是共享库,pathname会重复出现,表示共享库的代码段、数据段等,代码段具有“r-x-”样式,而数据段具有“rw–”样式。

You might notice a lot of anonymous regions. These are usually created by mmap but are not attached to any file. They are used for a lot of miscellaneous things like shared memory or buffers not allocated on the heap. For instance, I think the pthread library uses anonymous mapped regions as stacks for new threads.[4]

相关工具

  • pmap

/proc/pid/smaps文件

smaps文件是基于maps文件的拓展,更详细地展示了进程内存映射的mapping和flags信息。

实现代码在fs/proc/task_mmu.c:show_smap

smaps文件的输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#address perms offset dev inode pathname
08048000-080bc000 r-xp 00000000 03:02 13130 /bin/bash
Size: 1084 kB
Rss: 892 kB
Pss: 374 kB
Shared_Clean: 892 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 0 kB
Referenced: 892 kB
Anonymous: 0 kB
LazyFree: 0 kB
AnonHugePages: 0 kB
ShmemPmdMapped: 0 kB
Shared_Hugetlb: 0 kB
Private_Hugetlb: 0 kB
Swap: 0 kB
SwapPss: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Locked: 0 kB
VmFlags: rd ex mr mw me dw

  • Size:相应虚拟地址空间的大小(the size of the mapping)
  • Rss(Resident Set Size): 常驻内存大小
  • Pss(Proportional Set Size):Unshared memory(Uss) + proportion of shared memory
  • Uss(Unique Set Size ):Pss中独占的部分
  • Shared_Clean: 共享页中干净的页数
  • Shared_Dirty: 共享页中脏页的页数
  • Private_Clean: 私有页中干净的页数
  • Private_Dirty: 私有页中脏页的页数

Rss=Shared_Clean+Shared_Dirty+Private_Clean+Private_Dirty

if n processes are sharing a library L with size M then the contribution to their PSS is M/n.
So Pss = Uss + M/n

  • Swap: 表示非mmap内存(也叫anonymous memory,比如malloc动态分配出来的内存)由于物理内存不足被swap到交换空间的大小。
类型 说明 details
Shared page的引用>1 shared pages are mappedby other processes
Private page的引用=1 Private pages are available only to that process
Dirty page的flags设置了_PAGE_DIRTY,当发生换页时要写回磁盘 Dirty pages are pages that are not clean (i.e. have been modified)
Clean page的flags未设置 _PAGE_DIRTY,当发生换页时不用写回 Clean pages are pages that have not been modified since they were mapped
(typically, text sections from shared libraries are only read from disk (when necessary), never modified, so they’ll be in shared, clean pages)
参考链接: