了解系统的内存消耗是运维最基本的技能,但是Linux中关于内存消耗的指标很容易让人混淆,本文尝试把诸多概念解释清楚
物理内存:不解释 虚拟内存:进程独享,由操作系统通过地址映射的方式,转换为对物理内存的访问。在32位Linux机器上,每个进程的虚拟内存都是4G。(这里的虚拟内存与操作系统使用中过程常见的虚拟内存概念不同,不要混淆了,如Linux中swap)
top - 21:58:44 up 4:45, 3 users, load average: 2.57, 1.72, 0.75
Tasks: 108 total, 1 running, 107 sleeping, 0 stopped, 0 zombie
%Cpu(s): 5.9 us, 5.9 sy, 0.0 ni, 88.2 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1865252 total, 542664 free, 459884 used, 862704 buff/cache
KiB Swap: 2097148 total, 2097148 free, 0 used. 1144688 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 127936 6576 4128 S 0.0 0.4 0:01.33 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:00.63 ksoftirqd/0
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
pmap
命令查看详情。并不是真实内存耗费,比如我们可以通过命令java -Xms1024m -Xmx40960m Hello
就可以得到VIRT为41G的进程。$ ps aux | head
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.3 127936 6576 ? Ss 17:12 0:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root 2 0.0 0.0 0 0 ? S 17:12 0:00 [kthreadd]
smem
命令可以得到USS, PSS,更能反映进程的真实内存消耗
$ smem
PID User Command Swap USS PSS RSS
111965 root -bash 0 504 757 2164
113696 root -bash 0 512 779 2200
1553 root -bash 0 516 783 2204
10556 root top 0 868 968 2292
18799 root python /usr/bin/smem 0 4712 5169 6892
112580 root java -Xms1024m -Xmx40960m A 0 31036 31076 32040
/proc/{pid}/status
/proc/{pid}/maps
man ps
得到以下解释:The SIZE and RSS fields don't count some parts of a process including the page tables, kernel stack, struct thread_info, and struct task_struct. This is usually at least 20 KiB of memory that is always resident. SIZE is the virtual size of the process (code+data+stack).