介绍
vmstat 命令是VirtualMeomory Statistics (虚拟内存统计)的缩写。是针对系统的整体情况(虚拟内存、进程、CPU)的监控,而对进程进行监控的是top
首先,谈一谈什么是虚拟内存,以及虚拟内存和物理内存的区别。
物理内存是系统硬件,真正的内存,读写数据是非常快,但内存的容量非常小,是有限的,这就引出了虚拟内存。虚拟内存 就是为了满足物理内存不足,而利用磁盘空间虚拟出来的一个逻辑内存。这段磁盘空间就被称为交换分区(swap space)。
虚拟内存作为物理内存的扩展,在物理内存不足时,linux将会使用交换分区的虚拟内存,linux内核会将暂时不用的内存块信息写到交换空间,这样,物理内存得到了释放,这块内存就可以用于其他,但需要用到原始内容时,这些信息会被重新从交换分区读入物理内存。
linux的内存管理采取的是分页存取机制,为了保证物理内存能得到充分的利用,内核会在适当的时候将物理内存中不经常使用的数据块自动交换到虚拟内存中,而将经常使用的信息保留到物理内存。
linux系统会时不时的进行页面交换操作,以保持尽可能多的空闲物理内存,即使并没有什么事情需要内存,Linux也会出现交换暂时不用的内存页面,这可以避免等待交换所需的时间。
Linux进行页面交换也是有条件的,不是所有页面在不用时都交换到虚拟内存,Linux内核根据“最近最经常使用”算法,仅仅将一些不经常使用的页面文件交换到虚拟内存,有时我们会看到这么一个现象:linux物理内存还有很多,但是交换空间也使用了很多。其实,这并不奇怪,例如,一个占用很大内存的进程运行时,需要耗费很多内存资源,此时就会有一些不常用页面文件被交换到虚拟内存中,但后来这个占用很多内存资源的进程结束并释放了很多内存时,刚才被交换出去的页面文件并不会自动的交换进物理内存,除非有这个必要,那么此刻系统物理内存就会空闲很多,同时交换空间也在使用,就出了刚才所说的这一现象。
交换空间的页面在使用时会被首先交换到物理内存,如果此时没有足够的物理内存来容纳这些页面,他们又会被马上交换出去,如此一来,虚拟内存中没有足够空间来存储这些交换页面,最终会导致linux假死机、服务异常等问题,Linux虽然可以在一段时间内自行恢复,但是恢复后的系统已经基本不可用了。
虚拟内存原理
在系统中运行的每个进程都需要使用到内存,但不是每个进程都需要每时每刻使用系统分配的内存空间。当系统运行所需内存超过实际的物理内存,内核会释放某些进程所占用但未使用的部分或所有物理内存,将这部分资料存储在磁盘上直到进程下一次调用,并将释放出的内存提供给有需要的进程使用。
在Linux内存管理中,主要是通过“调页Paging”和“交换Swapping”来完成上述的内存调度。调页算法是将内存中最近不常使用的页面换到磁盘上,把活动页面保留在内存中供进程使用。交换技术是将整个进程,而不是部分页面,全部交换到磁盘上。
分页(Page)写入磁盘的过程被称作Page-Out,分页(Page)从磁盘重新回到内存的过程被称作Page-In。当内核需要一个分页时,但发现此分页不在物理内存中(因为已经被Page-Out了),此时就发生了分页错误(Page Fault)。
当系统内核发现可运行内存变少时,就会通过Page-Out来释放一部分物理内存。尽管Page-Out不是经常发生,但是如果Page-out频繁不断的发生,直到当内核管理分页的时间超过运行程式的时间时,系统效能会急剧下降。这时的系统已经运行非常慢或进入暂停状态,这种状态亦被称作thrashing(颠簸)。
命令
一般vmstat工具是通过两个数字参数完成的,第一个参数是采样的时间间隔数,单位是秒,第二个参数是采样的次数。
root@ubuntu:~# vmstat 2 1
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
1 0 0 3498472 315836 3819540 0 0 0 1 2 0 0 0 100 0
# 2表示每个两秒采集一次服务器状态,1表示只采集一次。
参数说明
procs(进程)
- r 运行队列中的进程(多少个进程真的分配到cpu)数量;一般负载超过了3就比较高,超过了5就高,超过了10就不正常了。如果运行队列过大,表示CPU很繁忙,一般会造成CPU使用率很高
- b 等待IO的进程(阻塞的进程)数量
memory(内存)
- swps 使用虚拟内存的大小;如果大于0,表示机器物理内存不足了,如果不是程序内存泄漏的原因,那么需要升级内存或者把耗内存的任务迁移到其他机器上。
- free 可用内存大小
- buff 用作缓冲的内存大小;
- cache 用作缓存的内存大小
swap
- si 每秒从交换区写到内存的大小;如果大于0,表示物理内存不够用或者内存泄漏,需要查找耗内存进程kill掉。
- so 每秒写入交换区的内存大小;如果大于0,同上。
IO
- bi 每秒读取块设备的块数;这里的块设备是指系统上所有的磁盘和其他块设备,默认块大小是1024byte。
- bo每秒写入块设备的块数;例如我们读取文件,bo就要大于0。bi和bo一般都要接近0,不然就是IO过于频繁,需要调整。
system
- in 每秒CPU的中断数,包括时钟中断
- cs 每秒上下文切换数;例如我们调用系统函数,就要进行上下文切换,线程的切换,也要进程上下文切换,这个值要越小越好,太大了,要考虑调低线程或者进程的数目,
例如在apache和nginx这种web服务器中,我们一般做性能测试时会进行几千并发甚至几万并发的测试,选择web服务器的进程可以由进程或者线程的峰值一直下调,
压测,直到cs到一个比较小的值,这个进程和线程数就是比较合适的值了。系统调用也是,每次调用系统函数,我们的代码就会进入内核空间,导致上下文切换,
这个是很耗资源,也要尽量避免频繁调用系统函数。上下文切换次数过多表示你的CPU大部分浪费在上下文切换,导致CPU干正经事的时间少了,CPU没有充分利用,是不可取的。
CPU
- us用户进程执行时间;用户CPU时间
- sy系统进程执行时间;系统CPU时间
- id空闲时间(包括IO等待时间),中央处理器的空闲时间。以百分比表示。空闲CPU使用率;一般来说,id+us+sy=100
- wa 等待IO时间
举例
vmstat -a 2 2
#-a 显示活跃和非活跃内存
vmstat -f
#-f 显示从系统启动到现在的fork数量
vmstat -s
# -s 显示内存相关统计信息及多种系统活动数量
vmstat -d
#-d 查看磁盘读写
vmstat -p /dev/sda1
#-p /dev/sda1 显示指定磁盘分区统计信息
vmstat -m
#-m 查看系统的slab信息
#slab:由于内核会有许多小对象,这些对象构造销毁十分频繁,比如i-node,dentry,这些对象如果每次构建的时候就向内存要一个页(4kb),这样就会非常浪费,为了解决这个问题,就引入了一种新的机制来处理
#在同一个页框中如何分配小存储区,而slab可以对小对象进行分配,这样就不用为每一个对象分配页框,从而节省了空间,内核对一些小对象创建析构很频繁,slab对这些小对象进行缓冲,可以重复利用,减少内存分配次数。