linux 下面查看內存有多種渠道,比如通過命令 ps ,top,free 等,比如通過/proc系統,一般需要比較詳細和精確地知道整機內存/某個進程內存的使用情況,最好通過/proc 系統,下面介紹/proc系統下內存相關的幾個文件
單個進程的內存查看 cat /proc/[pid] 下面有幾個文件: maps , smaps, status
maps 文件可以查看某個進程的代碼段、棧區、堆區、動態庫、內核區對應的虛擬地址,如果你還不了解linux進程的內存空間,可以參考這里。
下圖是maps文件內存示例
Develop>cat /proc/self/maps 00400000-0040b000 r-xp 00000000 fd:00 48 /mnt/cf/orig/root/bin/cat 0060a000-0060b000 r--p 0000a000 fd:00 48 /mnt/cf/orig/root/bin/cat 0060b000-0060c000 rw-p 0000b000 fd:00 48 /mnt/cf/orig/root/bin/cat 代碼段 0060c000-0062d000 rw-p 00000000 00:00 0 [heap] 堆區 7f1fff43b000-7f1fff5d4000 r-xp 00000000 fd:00 861 /mnt/cf/orig/root/lib64/libc-2.15.so 7f1fff5d4000-7f1fff7d3000 ---p 00199000 fd:00 861 /mnt/cf/orig/root/lib64/libc-2.15.so 7f1fff7d3000-7f1fff7d7000 r--p 00198000 fd:00 861 /mnt/cf/orig/root/lib64/libc-2.15.so 7f1fff7d7000-7f1fff7d9000 rw-p 0019c000 fd:00 861 /mnt/cf/orig/root/lib64/libc-2.15.so 7f1fff7d9000-7f1fff7dd000 rw-p 00000000 00:00 0 7f1fff7dd000-7f1fff7fe000 r-xp 00000000 fd:00 2554 /mnt/cf/orig/root/lib64/ld-2.15.so 7f1fff9f9000-7f1fff9fd000 rw-p 00000000 00:00 0 7f1fff9fd000-7f1fff9fe000 r--p 00020000 fd:00 2554 /mnt/cf/orig/root/lib64/ld-2.15.so 7f1fff9fe000-7f1fff9ff000 rw-p 00021000 fd:00 2554 /mnt/cf/orig/root/lib64/ld-2.15.so 7f1fff9ff000-7f1fffa00000 rw-p 00000000 00:00 0 7fff443de000-7fff443ff000 rw-p 00000000 00:00 0 [stack] 用戶態棧區
7fff443ff000-7fff44400000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] 內核區
有時候可以通過不斷查看某個進程的maps文件,通過查看其虛擬內存(堆區)是否不停增長來簡單判斷進程是否發生了內存溢出。
maps文件只能顯示簡單的分區,smap文件可以顯示每個分區的更詳細的內存占用數據
下圖是smaps文件內存示例, 實際顯示內容會將每一個區都顯示出來,下面我只拷貝了代碼段和堆區,
每一個區顯示的內容項目是一樣的,smaps文件各項含義可以參考這里
Develop>cat /proc/self/smaps 00400000-0040b000 r-xp 00000000 fd:00 48 /mnt/cf/orig/root/bin/cat Size: 44 kB 虛擬內存大小 Rss: 28 kB 實際使用物理內存大小 Pss: 28 kB Shared_Clean: 0 kB 頁面被改,則是dirty,否則是clean,頁面引用計數>1,是shared,否則是private Shared_Dirty: 0 kB Private_Clean: 28 kB Private_Dirty: 0 kB Referenced: 28 kB Anonymous: 0 kB AnonHugePages: 0 kB Swap: 0 kB 處於交換區的頁面大小 KernelPageSize: 4 kB 操作系統一個頁面大小 MMUPageSize: 4 kB 體系結構MMU一個頁面大小 Locked: 0 kB
0060c000-0062d000 rw-p 00000000 00:00 0 [heap]
Size: 132 kB
Rss: 8 kB
Pss: 8 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 8 kB
Referenced: 8 kB
Anonymous: 8 kB
AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 4 kB
MMUPageSize: 4 kB
Locked: 0 kB
下圖是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
可以看到,linux下內存占用是一個比較復雜的概念,不能
簡單通過一個單一指標就判斷某個程序“內存消耗”大小,原因有下面2點:
- 進程所申請的內存不一定真正會被用到(malloc或mmap的實現)
- 真正用到了的內存也不一定是只有該進程自己在用 (比如動態共享庫)
關於內存的使用分析及本文幾個命令的說明也可以參考這里
下面是查看整機內存使用情況的文件 /proc/meminfo
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