天天看點

Linux proc 記憶體

ps:

USER      PID    %CPU %MEM   VSZ   RSS  TTY  STAT  START  TIME  COMMAND 

root          4238     0.0        0.0     52396  352   pts/0    S       21:29    0:00   ./prog 

VSZ指的是程序記憶體空間的大小,這裡是52396KB; 

RSS指的是駐留實體記憶體中的記憶體大小,這裡是352KB。 

一般系統管理者知道VSZ并不代表程序真正用到的記憶體,因為有些空間會僅在頁表中挂個名,也就是說隻是虛拟存在着,隻有真正用到的時候核心才會把虛拟頁面和真正的實體頁面映射起來。比如,prog.c中用malloc()配置設定的32MB記憶體,由于程式中并沒有用到這些記憶體,沒有實體記憶體被配置設定,也就不應算到程序的帳上。 

程序的記憶體使用情況比較複雜,這是因為: 

    • 程序所申請的記憶體不一定真正會被用到
    • 真正用到了的記憶體也不一定是隻有該程序自己在用 (比如動态共享庫)

有效的實際使用記憶體 = 該程序獨占的記憶體 + 共享的記憶體A /共享A的程序數目 + 共享的記憶體B /共享B的程序數目 + ... 

free -m

total(96679)表示系統中實體記憶體總量。 

used(1631)表示已經配置設定的實體記憶體。 

free(95048)表示尚未配置設定的實體記憶體。 

shared(0)表示共享記憶體。 

buffers(196)表示配置設定給用作buffer的記憶體。 

cached(283)表示配置設定給用作cached的記憶體。 

第二行: 

-buffers/cache(1151): 第一行中的used - buffers - cached 

+buffer/cache(95528): 第一行中的free + buffers + cached 

說明:資料會有些許的誤差,猜測是四舍五入引起的。 

-buffers/cache可以表示被程序實實在在消耗掉的記憶體。 

+buffers/cache可以表示還可以配置設定的記憶體大小。因為buffers/cache還可以被壓縮。 

buffers和cache的差別: 

A buffer is something that has yet to be “written” to disk. A cache is something that has been “read” from the disk and stored for later use. 

第三行: 

交換區。當記憶體不夠用的時候,系統會選擇合适的程序,将其交換到swap區,把它占用的記憶體重新配置設定給其他程序。第三行表示swap區的大小和已經被使用掉的空間。

maps

Each row in 

/proc/$PID/maps

 describes a region of contiguous virtual memory in a process or thread. Each row has the following fields:

address           perms offset  dev   inode   pathname
08048000-08056000 r-xp 00000000 03:0c 64593   /usr/sbin/gpm
           
  • address - This is the starting and ending address of the region in the process's address space
  • permissions - This describes how pages in the region can be accessed. There are four different permissions: read, write, execute, and shared. If read/write/execute are disabled, a '-' will appear instead of the 'r'/'w'/'x'. If a region is not shared, it is private, so a 'p' will appear instead of an 's'. 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.
  • offset - If the region was mapped from a file (using 

    mmap

    ), this is the offset in the file where the mapping begins. If the memory was not mapped from a file, it's just 0.
  • device - 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.
  • pathname - If the region was mapped from a file, this is the name of the file. This field is blank for anonymous mapped regions. There are also special regions with names like 

    [heap]

    [stack]

    , or 

    [vdso]

    [vdso]

     stands for virtual dynamic shared object. It's used by system calls to switch to kernel mode. Here's a good article about it.

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

The format of the file is:

    address           perms offset  dev   inode       pathname
    00400000-00452000 r-xp 00000000 08:02 173521      /usr/bin/dbus-daemon
    00651000-00652000 r--p 00051000 08:02 173521      /usr/bin/dbus-daemon
    00652000-00655000 rw-p 00052000 08:02 173521      /usr/bin/dbus-daemon
    00e03000-00e24000 rw-p 00000000 00:00 0           [heap]
    00e24000-011f7000 rw-p 00000000 00:00 0           [heap]
    ...
    35b1800000-35b1820000 r-xp 00000000 08:02 135522  /usr/lib64/ld-2.15.so
    35b1a1f000-35b1a20000 r--p 0001f000 08:02 135522  /usr/lib64/ld-2.15.so
    35b1a20000-35b1a21000 rw-p 00020000 08:02 135522  /usr/lib64/ld-2.15.so
    35b1a21000-35b1a22000 rw-p 00000000 00:00 0
    35b1c00000-35b1dac000 r-xp 00000000 08:02 135870  /usr/lib64/libc-2.15.so
    35b1dac000-35b1fac000 ---p 001ac000 08:02 135870  /usr/lib64/libc-2.15.so
    35b1fac000-35b1fb0000 r--p 001ac000 08:02 135870  /usr/lib64/libc-2.15.so
    35b1fb0000-35b1fb2000 rw-p 001b0000 08:02 135870  /usr/lib64/libc-2.15.so
    ...
    f2c6ff8c000-7f2c7078c000 rw-p 00000000 00:00 0    [stack:986]
    ...
    7fffb2c0d000-7fffb2c2e000 rw-p 00000000 00:00 0   [stack]
    7fffb2d48000-7fffb2d49000 r-xp 00000000 00:00 0   [vdso]

              The address field is the address space in the process that the
              mapping occupies.  The perms field is a set of permissions:

                  r = read
                  w = write
                  x = execute
                  s = shared
                  p = private (copy on write)

              The offset field is the offset into the file/whatever; dev is
              the device (major:minor); inode is the inode on that device.
              0 indicates that no inode is associated with the memory
              region, as would be the case with BSS (uninitialized data).

              The pathname field will usually be the file that is backing
              the mapping.  For ELF files, you can easily coordinate with
              the offset field by looking at the Offset field in the ELF
              program headers (readelf -l).

              There are additional helpful pseudo-paths:

                   [stack]
                          The initial process's (also known as the main
                          thread's) stack.

                   [stack:<tid>] (since Linux 3.4)
                          A thread's stack (where the <tid> is a thread ID).
                          It corresponds to the /proc/[pid]/task/[tid]/
                          path.

                   [vdso] The virtual dynamically linked shared object.  See
                          vdso(7).

                   [heap] The process's heap.

              If the pathname field is blank, this is an anonymous mapping
              as obtained via mmap(2).  There is no easy way to coordinate
              this back to a process's source, short of running it through
              gdb(1), strace(1), or similar.      

status:

Develop>cat /proc/24475/status
Name:    netio   可執行程式的名字
State:    R (running) 任務狀态,運作/睡眠/僵死
Tgid:    24475  線程組号
Pid:    24475   程序id
PPid:    19635  父程序id
TracerPid:    0  
Uid:    0    0    0    0
Gid:    0    0    0    0
FDSize:    256 該程序最大檔案描述符個數
Groups:    0 
VmPeak:     6330708 kB  記憶體使用峰值

VmSize:      268876 kB 程序虛拟位址空間大小

VmLck:           0 kB 程序鎖住的實體記憶體大小,鎖住的實體記憶體無法交換到硬碟

VmHWM:       16656 kB

VmRSS:       11420 kB 程序正在使用的實體記憶體大小

VmData:      230844 kB 程序資料段大小

VmStk:         136 kB 程序使用者态棧大小

VmExe:         760 kB 程序代碼段大小

VmLib:        7772 kB 程序使用的庫映射到虛拟記憶體空間的大小

VmPTE:         120 kB 程序頁表大小
VmSwap:           0 kB
Threads:    5
SigQ:    0/63346
SigPnd:    0000000000000000
ShdPnd:    0000000000000000
SigBlk:    0000000000000000
SigIgn:    0000000001000000
SigCgt:    0000000180000000
CapInh:    0000000000000000
CapPrm:    ffffffffffffffff
CapEff:    ffffffffffffffff
CapBnd:    ffffffffffffffff
Cpus_allowed:    01
Cpus_allowed_list:    0
Mems_allowed:    01
Mems_allowed_list:    0
voluntary_ctxt_switches:    201
nonvoluntary_ctxt_switches:    909      

meminfo

下面是檢視整機記憶體使用情況的檔案 /proc/meminfo

Linux proc 記憶體
Develop>cat /proc/meminfo 
MemTotal:        8112280 kB 所有可用RAM大小 (即實體記憶體減去一些預留位和核心的二進制代碼大小)
MemFree:         4188636 kB LowFree與HighFree的總和,被系統留着未使用的記憶體
Buffers:           34728 kB 用來給檔案做緩沖大小
Cached:           289740 kB 被高速緩沖存儲器(cache memory)用的記憶體的大小
                           (等于 diskcache minus SwapCache )
SwapCached:            0 kB 被高速緩沖存儲器(cache memory)用的交換空間的大小 
                            已經被交換出來的記憶體,但仍然被存放在swapfile中。
                            用來在需要的時候很快的被替換而不需要再次打開I/O端口
Active:           435240 kB 在活躍使用中的緩沖或高速緩沖存儲器頁面檔案的大小,
                              除非非常必要否則不會被移作他用
Inactive:         231512 kB 在不經常使用中的緩沖或高速緩沖存儲器頁面檔案的大小,可能被用于其他途徑.
Active(anon):     361252 kB 
Inactive(anon):   120688 kB
Active(file):      73988 kB
Inactive(file):   110824 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB 交換空間的總大小
SwapFree:              0 kB 未被使用交換空間的大小
Dirty:                 0 kB 等待被寫回到磁盤的記憶體大小
Writeback:             0 kB 正在被寫回到磁盤的記憶體大小
AnonPages:        348408 kB 未映射頁的記憶體大小
Mapped:            33600 kB 已經被裝置和檔案等映射的大小
Shmem:            133536 kB 
Slab:              55984 kB 核心資料結構緩存的大小,可以減少申請和釋放記憶體帶來的消耗
SReclaimable:      25028 kB 可收回Slab的大小
SUnreclaim:        30956 kB 不可收回Slab的大小(SUnreclaim+SReclaimable=Slab)
KernelStack:        1896 kB 核心棧區大小
PageTables:         8156 kB 管理記憶體分頁頁面的索引表的大小
NFS_Unstable:          0 kB 不穩定頁表的大小
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     2483276 kB
Committed_AS:    1804104 kB
VmallocTotal:   34359738367 kB 可以vmalloc虛拟記憶體大小
VmallocUsed:      565680 kB 已經被使用的虛拟記憶體大小
VmallocChunk:   34359162876 kB
HardwareCorrupted:     0 kB
HugePages_Total:    1536  大頁面數目
HugePages_Free:        0 空閑大頁面數目
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB 大頁面一頁大小
DirectMap4k:       10240 kB 
DirectMap2M:     8302592 kB