Background
物理内存就是系统硬件提供的内存大小,是真正的内存,相对于物理内存,在linux下还有一个虚拟内存的概念,虚拟内存就是为了满足物理内存的不足而提出的策略,它是利用磁盘空间虚拟出的一块逻辑内存,用作虚拟内存的磁盘空间被称为交换空间(Swap Space)。
作为物理内存的扩展,linux会在物理内存不足时,使用交换分区的虚拟内存,更详细的说,就是内核会将暂时不用的内存块信息写到交换空间,这样以来,物理内存得到了释放,这块内存就可以用于其它目的,当需要用到原始的内容时,这些信息会被重新从交换空间读入物理内存。
linux的内存管理采取的是分页存取机制,为了保证物理内存能得到充分的利用,内核会在适当的时候将物理内存中不经常使用的数据块自动交换到虚拟内存中,而将经常使用的信息保留到物理内存。
在Linux内存管理中,主要是通过“调页Paging”和“交换Swapping”来完成上述的内存调度。调页算法是将内存中最近不常使用的页面换到磁盘上,把活动页面保留在内存中供进程使用。交换技术是将整个进程,而不是部分页面,全部交换到磁盘上。
分页(Page)写入磁盘的过程被称作Page-Out,分页(Page)从磁盘重新回到内存的过程被称作Page-In。当内核需要一个分页时,但发现此分页不在物理内存中(因为已经被Page-Out了),此时就发生了分页错误(Page Fault)。
dmesg
- OOM 问题
$ dmesg -T
可以查看是否有进程因为 OOM(out-of memory)被OOM killer kill 掉。
找到使用内存最多的进程
This will show you top 10 process that using the most memory:
ps aux --sort=-%mem | head
# or
ps -o pid,user,%mem,command ax | sort -b -k3 -r
# or
ps aux | sort -rnk 4 | head -5
Or
Use htop
, hit F6
and choose Sort by M_SIZE
free
$ free -h -w -t
total used free shared buffers cache available
Mem: 8.0G 3.1G 3.2G 0B 0B 1.6G 4.9G
Swap: 0B 0B 0B
Total: 8.0G 3.1G 3.2G
- total: Total
- installed memory (MemTotal and SwapTotal in /proc/meminfo)
- used: Used memory (calculated as total - free - buffers - cache)
- b: Unused memory (MemFree and SwapFree in /proc/meminfo)
- shared: Memory used (mostly) by tmpfs (Shmem in /proc/meminfo)
- buffers: Memory used by kernel buffers (Buffers in /proc/meminfo)
- cache: Memory used by the page cache and slabs (Cached and SReclaimable in /proc/meminfo)
- buff/cache: Sum of buffers and cache
- available: Estimation of how much memory is available for starting new applications, without swapping. Unlike the data provided by the cache or free fields, this field takes into account page cache and also that not all reclaimable memory slabs will be reclaimed due to items being in use (MemAvailable in /proc/meminfo, available on kernels 3.14, emulated on kernels 2.6.27+, otherwise the same as free)
Parameters
Usage:
free [options]
Options:
-b, --bytes show output in bytes
-k, --kilo show output in kilobytes
-m, --mega show output in megabytes
-g, --giga show output in gigabytes
--tera show output in terabytes
-h, --human show human-readable output
--si use powers of 1000 not 1024
-l, --lohi show detailed low and high memory statistics
-t, --total show total for RAM + swap
-s N, --seconds N repeat printing every N seconds
-c N, --count N repeat printing N times, then exit
-w, --wide wide output
--help display this help and exit
-V, --version output version information and exit
vmstat - 查看内存及虚拟内存使用
vmstat reports information about processes, memory, paging, block IO, traps, disks and cpu activity.
Usage:
vmstat [options] [delay [count]]
Options:
-a, --active active/inactive memory
-f, --forks number of forks since boot
-m, --slabs slabinfo
-n, --one-header do not redisplay header
-s, --stats event counter statistics
-d, --disk disk statistics
-D, --disk-sum summarize disk statistics
-p, --partition <dev> partition specific statistics
-S, --unit <char> define display unit, options: k, K, m or M
-w, --wide wide output
-t, --timestamp show timestamp
-h, --help display this help and exit
-V, --version output version information and exit
vmstat -S M -w 1
- Common Usage
加宽输出,1s更新一次,单位为MB:
$ vmstat -S M -w 1
procs -----------------------memory---------------------- ---swap-- -----io---- -system-- --------cpu--------
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 1 0 4106 116 3086 0 0 0 1 1 0 0 0 100 0 0
0 0 0 4107 116 3086 0 0 0 4 111 123 0 0 100 0 0
0 0 0 4107 116 3086 0 0 0 16 41 68 0 0 100 0 0
0 0 0 4107 116 3086 0 0 0 0 43 71 0 0 100 0 0
0 0 0 4107 116 3086 0 0 0 0 56 92 0 0 100 0 0
0 0 0 4107 116 3086 0 0 0 0 31 53 0 0 100 0 0
0 0 0 4107 116 3086 0 0 0 16 39 71 0 0 100 0 0
0 0 0 4107 116 3086 0 0 0 8 58 94 0 0 100 0 0
0 0 0 4106 116 3086 0 0 0 0 84 122 0 0 100 0 0
0 0 0 4106 116 3086 0 0 0 0 33 51 0 0 100 0 0
0 0 0 4106 116 3086 0 0 0 0 53 95 0 0 100 0 0
0 0 0 4106 116 3086 0 0 0 0 33 59 0 0 100 0 0
0 0 0 4106 116 3086 0 0 0 0 41 78 0 0 100 0 0
0 0 0 4106 116 3086 0 0 0 0 47 68 0 0 100 0 0
0 0 0 4106 116 3086 0 0 0 0 31 58 0 0 100 0 0
0 0 0 4106 116 3086 0 0 0 0 273 406 0 0 100 0 0
0 0 0 4106 116 3086 0 0 0 0 58 97 0 0 100 0 0
0 0 0 4106 116 3086 0 0 0 0 40 68 0 0 100 0 0
Procs(进程):
- r: 运行队列中进程数量(The number of processes waiting for run time)
- b: 等待IO的进程数量(The number of processes in uninterruptible sleep)
Memory(内存):
- swpd: 使用虚拟内存大小(the amount of virtual memory used)
- free: 可用内存大小(the amount of idle memory)
- buff: 用作缓冲的内存大小(the amount of memory used as buffers)
- cache: 用作缓存的内存大小(the amount of memory used as cache)
Swap:
- si: 每秒从交换区写到内存的大小(Amount of memory swapped in from disk (/s))
- so: 每秒写入交换区的内存大小(Amount of memory swapped to disk (/s))
IO:
(现在的Linux版本块的大小为1024bytes)
- bi: 每秒读取的块数(Blocks received from a block device (blocks/s))
- bo: 每秒写入的块数(Blocks sent to a block device (blocks/s))
system:
- in: 每秒中断数,包括时钟中断(The number of interrupts per second, including the clock)
- cs: 每秒上下文切换数(The number of context switches per second)
CPU(以百分比表示)
- us: 用户进程执行时间(user time)- Time spent running non-kernel code
- sy: 系统进程执行时间(system time)- Time spent running kernel code
- id: 空闲时间(包括IO等待时间)- Time spent idle. Prior to Linux 2.5.41, this includes IO-wait time
- wa: 等待IO时间 - Time spent waiting for IO. Prior to Linux 2.5.41, included in idle
- st: Time stolen from a virtual machine. Prior to Linux 2.6.11, unknown
Analysis
注意:如果r(运行队列中进程数量)经常大于4 ,且id(CPU 空闲时间)经常少于40%,表示 CPU 的负荷很重。如果bi(每秒从磁盘交换区写到内存的块的数量),bo (每秒写入磁盘交换区的块的数量)长期不等于0,表示内存不足。
通过 vmstat
识别CPU瓶颈:
- r(运行队列)展示了正在执行和等待CPU资源的任务个数。当这个值超过了CPU数目,就会出现CPU瓶颈了。
Linux下查看CPU核心数的命令:
$ cat /proc/cpuinfo|grep processor|wc -l
当r值超过了CPU个数,就会出现CPU瓶颈,解决办法大体几种:
- 最简单的就是增加CPU个数和核数
- 通过调整任务执行时间,如大任务放到系统不繁忙的情况下进行执行,进而平衡系统任务
- 调整已有任务的优先级
通过 vmstat
识别CPU满负荷:
首先需要声明一点的是,vmstat中CPU的度量是百分比的。当us+sy(用户进程执行时间 + 系统进程执行时间)的值接近100的时候,表示CPU正在接近满负荷工作。但要注意的是,CPU 满负荷工作并不能说明什么,Linux总是试图要CPU尽可能的繁忙,使得任务的吞吐量最大化。唯一能够确定CPU瓶颈的还是r(运行队列)的值。
通过 vmstat
识别RAM瓶颈:
首先用free查看RAM的数量:
$ free -h
total used free shared buff/cache available
Mem: 7.3G 153M 4.0G 89M 3.1G 6.7G
Swap: 0B 0B 0B
- 当内存的需求大于RAM的数量,服务器启动了虚拟内存机制,通过虚拟内存,可以将RAM段移到SWAP DISK的特殊磁盘段上,这样会出现虚拟内存的页导出(Page-out)和页导入(Page-in)现象;
- 页导出并不能说明RAM瓶颈,虚拟内存系统经常会对内存段进行页导出,但页导入操作就表明了服务器需要更多的内存了, 页导入需要从SWAP DISK上将内存段复制回RAM,导致服务器速度变慢。
vmstat -s
- 查看内存使用的详细信息
$ vmstat -s
7642844 K total memory
157644 K used memory
724120 K active memory
2332472 K inactive memory
4205700 K free memory
119140 K buffer memory
3160360 K swap cache
0 K total swap
0 K used swap
0 K free swap
407491 non-nice user cpu ticks
121 nice user cpu ticks
388531 system cpu ticks
2132614502 idle cpu ticks
67627 IO-wait cpu ticks
0 IRQ cpu ticks
10148 softirq cpu ticks
155999 stolen cpu ticks
713412 pages paged in
20725480 pages paged out
0 pages swapped in
0 pages swapped out
157302182 interrupts
260885596 CPU context switches
1603299411 boot time
603894 forks
vmstat -d -S M
- 查看磁盘的读/写
$ vmstat -d -S M
disk- ------------reads------------ ------------writes----------- -----IO------
total merged sectors ms total merged sectors ms cur sec
loop0 10 0 32 0 0 0 0 0 0 0
loop1 0 0 0 0 0 0 0 0 0 0
loop2 0 0 0 0 0 0 0 0 0 0
loop3 0 0 0 0 0 0 0 0 0 0
loop4 0 0 0 0 0 0 0 0 0 0
loop5 0 0 0 0 0 0 0 0 0 0
loop6 0 0 0 0 0 0 0 0 0 0
loop7 0 0 0 0 0 0 0 0 0 0
sr0 0 0 0 0 0 0 0 0 0 0
vda 24507 157 1426792 9652 2125511 2428541 41451976 864024 0 79
merged:表示一次来自于合并的写/读请求,一般系统会把多个连接/邻近的读/写请求合并到一起来操作.
Reads
- total: Total reads completed successfully
- merged: grouped reads (resulting in one I/O)
- sectors: Sectors read successfully
- ms: milliseconds spent reading
Writes
- total: Total writes completed successfully
- merged: grouped
- writes (resulting in one I/O)
- sectors: Sectors written successfully
- ms: milliseconds spent writing
IO
- cur: I/O in progress
- s: seconds spent for I/O
sar
sar -r
- 查看 Memory 使用
sar -r: 指定-r之后,可查看物理内存使用状况:
$ sar -r 1 3
... 05/07/2020 _x86_64_ (1 CPU)
08:16:42 AM kbmemfree kbmemused %memused kbbuffers kbcached kbcommit %commit kbactive kbinact kbdirty
08:16:43 AM 260984 730648 73.68 28252 179944 2226192 177.56 407532 153884 0
08:16:44 AM 260792 730840 73.70 28252 179944 2226192 177.56 407536 153884 0
08:16:45 AM 260792 730840 73.70 28252 179944 2226192 177.56 407544 153884 0
Average: 260856 730776 73.69 28252 179944 2226192 177.56 407537 153884 0
$ free
total used free shared buff/cache available
Mem: 991632 433948 260872 9736 296812 360060
Swap: 262140 118760 143380
- kbmemfree:这个值和free命令中的free值基本一致,所以它不包括buffer和cache的空间
- kbmemused:这个值和free命令中的used值基本一致,所以它包括buffer和cache的空间
- %memused:物理内存使用率,这个值是kbmemused和内存总量(不包括swap)的一个百分比
- kbbuffers和kbcached:这两个值就是free命令中的buffer和cache
- kbcommit:保证当前系统所需要的内存,,即为了确保不溢出而需要的内存(RAM+swap)
- %commit:这个值是kbcommit与内存总量(包括swap)的一个百分比
sar -W
- 查看页面交换发生状况
页面发生交换时,服务器的吞吐量会大幅下降;服务器状况不良时,如果怀疑因为内存不足而导致了页面交换的发生,可以使用这个命令来确认是否发生了大量的交换;
$ sar -W
08:00:01 AM pswpin/s pswpout/s
08:10:01 AM 0.00 0.00
08:20:01 AM 0.00 0.00
Average: 0.00 0.00
- pswpin/s:每秒系统换入的交换页面(swap page)数量
- pswpout/s:每秒系统换出的交换页面(swap page)数量
Reference
-
man vmstat
-
https://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/vmstat.html
-
https://www.cnblogs.com/peida/archive/2012/12/25/2833108.html
-
https://unix.stackexchange.com/questions/166558/how-to-check-which-process-is-using-most-memory