每天一個 Linux 命令:vmstat 命令

vmstatVirtual Meomory Statistics(虛擬內存統計)的縮寫,可對操作系統的虛擬內存、進程、CPU 活動進行監控。他是對系統的整體情況進行統計,不足之處是無法對某個進程進行深入分析。

vmstat 工具提供了一種低開銷的系統性能觀察方式。因爲 vmstat 本身就是低開銷工具,在非常高負荷的服務器上,你需要查看並監控系統的健康情況,在控制窗口還是能夠使用 vmstat 輸出結果。

在學習 vmstat 命令前,我們先了解一下 Linux 系統中關於物理內存和虛擬內存相關信息。

物理內存和虛擬內存區別:

我們知道,直接從物理內存讀寫數據要比從硬盤讀寫數據要快的多,因此,我們希望所有數據的讀取和寫入都在內存完成,而內存是有限的,這樣就引出了物理內存與虛擬內存的概念。

物理內存就是系統硬件提供的內存大小,是真正的內存,相對於物理內存,在 linux 下還有一個虛擬內存的概念,虛擬內存就是爲了滿足物理內存的不足而提出的策略,它是利用磁盤空間虛擬出的一塊邏輯內存,用作虛擬內存的磁盤空間被稱爲交換空間(Swap Space)。

作爲物理內存的擴展,linux 會在物理內存不足時,使用交換分區的虛擬內存,更詳細的說,就是內核會將暫時不用的內存塊信息寫到交換空間,這樣以來,物理內存得到了釋放,這塊內存就可以用於其它目的,當需要用到原始的內容時,這些信息會被重新從交換空間讀入物理內存。

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(顛簸)。

1.命令格式:

vmstat [-a] [-n] [-S unit] [delay [ count]]

vmstat [-s] [-n] [-S unit]

vmstat [-m] [-n] [delay [ count]]

vmstat [-d] [-n] [delay [ count]]

vmstat [-p disk partition] [-n] [delay [ count]]

vmstat [-f]

vmstat [-V]

2.命令功能:

用來顯示虛擬內存的信息

3.命令參數:

-a:顯示活躍和非活躍內存

-f:顯示從系統啓動至今的 fork 數量 。

-m:顯示 slabinfo

-n:只在開始時顯示一次各字段名稱。

-s:顯示內存相關統計信息及多種系統活動數量。

delay:刷新時間間隔。如果不指定,只顯示一條結果。

count:刷新次數。如果不指定刷新次數,但指定了刷新時間間隔,這時刷新次數爲無窮。

-d:顯示磁盤相關統計信息。

-p:顯示指定磁盤分區統計信息

-S:使用指定單位顯示。參數有 k 、K 、m 、M ,分別代表 1000、1024、1000000、1048576 字節(byte)。默認單位爲 K(1024 bytes)

-V:顯示 vmstat 版本信息。

4.使用實例:

實例 1:顯示虛擬內存使用情況

命令:

vmstat

輸出:

[root@localhost ~]# vmstat 5 6
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 3029876 199616 690980    0    0     0     2    3    2  0  0 100  0  0
 0  0      0 3029752 199616 690980    0    0     0    41 1009   39  0  0 100  0  0
 0  0      0 3029752 199616 690980    0    0     0     3 1004   36  0  0 100  0  0
 0  0      0 3029752 199616 690980    0    0     0     4 1004   36  0  0 100  0  0
 0  0      0 3029752 199616 690980    0    0     0     6 1003   33  0  0 100  0  0
 0  0      0 3029752 199616 690980    0    0     0     5 1003   33  0  0 100  0  0

說明:

字段說明:

Procs(進程):

r: 運行隊列中進程數量

b: 等待 IO 的進程數量

Memory(內存):

swpd: 使用虛擬內存大小

free: 可用內存大小

buff: 用作緩衝的內存大小

cache: 用作緩存的內存大小

Swap:

si: 每秒從交換區寫到內存的大小

so: 每秒寫入交換區的內存大小

IO:(現在的 Linux 版本塊的大小爲 1024bytes)

bi: 每秒讀取的塊數

bo: 每秒寫入的塊數

系統:

in: 每秒中斷數,包括時鐘中斷。

cs: 每秒上下文切換數。

CPU(以百分比表示):

us: 用戶進程執行時間 (user time)

sy: 系統進程執行時間 (system time)

id: 空閒時間(包括 IO 等待時間), 中央處理器的空閒時間 。以百分比表示。

wa: 等待 IO 時間

備註:如果 r 經常大於 4 ,且 id 經常少於 40,表示 cpu 的負荷很重。如果 pi,po 長期不等於 0,表示內存不足。如果 disk 經常不等於 0, 且在 b 中的隊列 大於 3, 表示 io 性能不好。Linux 在具有高穩定性、可靠性的同時,具有很好的可伸縮性和擴展性,能夠針對不同的應用和硬件環境調整,優化出滿足當前應用需要的最佳性能。因此企業在維護 Linux 系統、進行系統調優時,瞭解系統性能分析工具是至關重要的。

命令:

vmstat 5 5

表示在 5 秒時間內進行 5 次採樣。將得到一個數據彙總他能夠反映真正的系統情況。

實例 2:顯示活躍和非活躍內存

命令:

vmstat -a 2 5

輸出:

[root@localhost ~]# vmstat -a 2 5
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
 r  b   swpd   free  inact active   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 3029752 387728 513008    0    0     0     2    3    2  0  0 100  0  0
 0  0      0 3029752 387728 513076    0    0     0     0 1005   34  0  0 100  0  0
 0  0      0 3029752 387728 513076    0    0     0    22 1004   36  0  0 100  0  0
 0  0      0 3029752 387728 513076    0    0     0     0 1004   33  0  0 100  0  0
 0  0      0 3029752 387728 513076    0    0     0     0 1003   32  0  0 100  0  0
[root@localhost ~]#

說明:

使用 - a 選項顯示活躍和非活躍內存時,所顯示的內容除增加 inact 和 active 外,其他顯示內容與例子 1 相同。

字段說明:

Memory(內存):

inact: 非活躍內存大小(當使用 - a 選項時顯示)

active: 活躍的內存大小(當使用 - a 選項時顯示)

實例 3:查看系統已經 fork 了多少次

命令:

vmstat -f

輸出:

[root@SCF1129 ~]# vmstat -f

   12744849 forks

[root@SCF1129 ~]#

說明:

這個數據是從 / proc/stat 中的 processes 字段裏取得的

實例 4:查看內存使用的詳細信息

命令:

vmstat -s

輸出:

[root@localhost ~]# vmstat -s
   4043760 total memory
   1013884 used memory
    513012 active memory
    387728 inactive memory
   3029876 free memory
    199616 buffer memory
    690980 swap cache
   6096656 total swap
      0 used swap
   6096656 free swap
    83587 non-nice user cpu ticks
     132 nice user cpu ticks
    278599 system cpu ticks
  913344692 idle cpu ticks
    814550 IO-wait cpu ticks
    10547 IRQ cpu ticks
    21261 softirq cpu ticks
      0 stolen cpu ticks
    310215 pages paged in
   14254652 pages paged out
      0 pages swapped in
      0 pages swapped out
  288374745 interrupts
  146680577 CPU context switches
  1351868832 boot time
    367291 forks

說明:

這些信息的分別來自於 / proc/meminfo,/proc/stat 和 / proc/vmstat。

實例 5:查看磁盤的讀 / 寫

命令:

vmstat -d

輸出:

[root@localhost ~]# vmstat -d
disk- ------------reads------------ ------------writes----------- -----IO------
       total merged sectors      ms  total merged sectors      ms    cur    sec
ram0       0      0       0       0      0      0       0       0      0      0
ram1       0      0       0       0      0      0       0       0      0      0
ram2       0      0       0       0      0      0       0       0      0      0
ram3       0      0       0       0      0      0       0       0      0      0
ram4       0      0       0       0      0      0       0       0      0      0
ram5       0      0       0       0      0      0       0       0      0      0
ram6       0      0       0       0      0      0       0       0      0      0
ram7       0      0       0       0      0      0       0       0      0      0
ram8       0      0       0       0      0      0       0       0      0      0
ram9       0      0       0       0      0      0       0       0      0      0
ram10      0      0       0       0      0      0       0       0      0      0
ram11      0      0       0       0      0      0       0       0      0      0
ram12      0      0       0       0      0      0       0       0      0      0
ram13      0      0       0       0      0      0       0       0      0      0
ram14      0      0       0       0      0      0       0       0      0      0
ram15      0      0       0       0      0      0       0       0      0      0
sda    33381   6455  615407   63224 2068111 1495416 28508288 15990289      0  10491
hdc        0      0       0       0      0      0       0       0      0      0
fd0        0      0       0       0      0      0       0       0      0      0
md0        0      0       0       0      0      0       0       0      0      0
[root@localhost ~]#

說明:

這些信息主要來自於 / proc/diskstats.

merged: 表示一次來自於合併的寫 / 讀請求,一般系統會把多個連接 / 鄰近的讀 / 寫請求合併到一起來操作。

實例 6:查看 / dev/sda1 磁盤的讀 / 寫

命令:

輸出:

[root@SCF1129 ~]# df

文件系統                 1K-塊      已用      可用 已用% 掛載點

/dev/sda3            1119336548  27642068 1034835500   3% /tmpfs                 32978376         0  32978376   0% /dev/shm

/dev/sda1              1032088     59604    920056   7% /boot

[root@SCF1129 ~]# vmstat -p /dev/sda1

sda1          reads   read sectors  writes    requested writes

               18607    4249978          6         48[root@SCF1129 ~]# vmstat -p /dev/sda3

sda3          reads   read sectors  writes    requested writes

              429350   35176268   28998789  980301488[root@SCF1129 ~]#

說明:

這些信息主要來自於 / proc/diskstats。

reads: 來自於這個分區的讀的次數。

read sectors: 來自於這個分區的讀扇區的次數。

writes: 來自於這個分區的寫的次數。

requested writes: 來自於這個分區的寫請求次數。

實例 7:查看系統的 slab 信息

命令:

vmstat -m

輸出:

[root@localhost ~]# vmstat -m
Cache            Num Total  Size Pages
ip_conntrack_expect      0   0  136   28
ip_conntrack         3   13  304   13
ip_fib_alias         11   59   64   59
ip_fib_hash         11   59   64   59
AF_VMCI            0   0  960   4
bio_map_info        100  105  1064   7
dm_mpath           0   0  1064   7
jbd_4k            0   0  4096   1
dm_uevent           0   0  2608   3
dm_tio            0   0   24  144
dm_io             0   0   48   77
scsi_cmd_cache        10   10  384   10
sgpool-128          32   32  4096   1
sgpool-64          32   32  2048   2
sgpool-32          32   32  1024   4
sgpool-16          32   32  512   8
sgpool-8           45   45  256   15
scsi_io_context        0   0  112   34
ext3_inode_cache     51080 51105  760   5
ext3_xattr          36   88   88   44
journal_handle        18  144   24  144
journal_head         56   80   96   40
revoke_table         4  202   16  202
revoke_record         0   0   32  112
uhci_urb_priv         0   0   56   67
UNIX             13   33  704   11
flow_cache          0   0  128   30
msi_cache          33   59   64   59
cfq_ioc_pool         14   90  128   30
cfq_pool           12   90  216   18
crq_pool           16   96   80   48
deadline_drq         0   0   80   48
as_arq            0   0   96   40
mqueue_inode_cache      1   4  896   4
isofs_inode_cache       0   0  608   6
hugetlbfs_inode_cache     1   7  576   7
Cache            Num Total  Size Pages
ext2_inode_cache       0   0  720   5
ext2_xattr          0   0   88   44
dnotify_cache         0   0   40   92
dquot             0   0  256   15
eventpoll_pwq         3   53   72   53
eventpoll_epi         3   20  192   20
inotify_event_cache      0   0   40   92
inotify_watch_cache      1   53   72   53
kioctx            0   0  320   12
kiocb             0   0  256   15
fasync_cache         0   0   24  144
shmem_inode_cache      254  290  768   5
posix_timers_cache      0   0  128   30
uid_cache           0   0  128   30
ip_mrt_cache         0   0  128   30
tcp_bind_bucket        3  112   32  112
inet_peer_cache        0   0  128   30
secpath_cache         0   0   64   59
xfrm_dst_cache        0   0  384   10
ip_dst_cache         5   10  384   10
arp_cache           1   15  256   15
RAW              3   5  768   5
UDP              5   10  768   5
tw_sock_TCP          0   0  192   20
request_sock_TCP       0   0  128   30
TCP              4   5  1600   5
blkdev_ioc          14  118   64   59
blkdev_queue         20   30  1576   5
blkdev_requests       13   42  272   14
biovec-256          7   7  4096   1
biovec-128          7   8  2048   2
biovec-64           7   8  1024   4
biovec-16           7   15  256   15
biovec-4           7   59   64   59
biovec-1           23  202   16  202
bio             270  270  128   30
utrace_engine_cache      0   0   64   59
Cache            Num Total  Size Pages
utrace_cache         0   0   64   59
sock_inode_cache       33   48  640   6
skbuff_fclone_cache      7   7  512   7
skbuff_head_cache      319  390  256   15
file_lock_cache        1   22  176   22
Acpi-Operand        4136  4248   64   59
Acpi-ParseExt         0   0   64   59
Acpi-Parse          0   0   40   92
Acpi-State          0   0   80   48
Acpi-Namespace       2871  2912   32  112
delayacct_cache       81  295   64   59
taskstats_cache        4   53   72   53
proc_inode_cache      1427  1440  592   6
sigqueue           0   0  160   24
radix_tree_node      13166 13188  536   7
bdev_cache          23   24  832   4
sysfs_dir_cache      5370  5412   88   44
mnt_cache          26   30  256   15
inode_cache        2009  2009  560   7
dentry_cache       60952 61020  216   18
filp            479  1305  256   15
names_cache          3   3  4096   1
avc_node           14   53   72   53
selinux_inode_security   994  1200   80   48
key_jar            2   20  192   20
idr_layer_cache       74   77  528   7
buffer_head       164045 164800   96   40
mm_struct          51   56  896   4
vm_area_struct       1142  1958  176   22
fs_cache           35  177   64   59
files_cache         36   55  768   5
signal_cache         72  162  832   9
sighand_cache        68   84  2112   3
task_struct         76   80  1888   2
anon_vma          458  864   24  144
pid             83  295   64   59
shared_policy_node      0   0   48   77
Cache            Num Total  Size Pages
numa_policy         37  144   24  144
size-131072(DMA)       0   0 131072   1
size-131072          0   0 131072   1
size-65536(DMA)        0   0 65536   1
size-65536          1   1 65536   1
size-32768(DMA)        0   0 32768   1
size-32768          2   2 32768   1
size-16384(DMA)        0   0 16384   1
size-16384          5   5 16384   1
size-8192(DMA)        0   0  8192   1
size-8192           7   7  8192   1
size-4096(DMA)        0   0  4096   1
size-4096          110  111  4096   1
size-2048(DMA)        0   0  2048   2
size-2048          602  602  2048   2
size-1024(DMA)        0   0  1024   4
size-1024          344  352  1024   4
size-512(DMA)         0   0  512   8
size-512          433  480  512   8
size-256(DMA)         0   0  256   15
size-256          1139  1155  256   15
size-128(DMA)         0   0  128   30
size-64(DMA)         0   0   64   59
size-64          5639  5782   64   59
size-32(DMA)         0   0   32  112
size-128          801  930  128   30
size-32          3005  3024   32  112
kmem_cache         137  137  2688   1

這組信息來自於 / proc/slabinfo。

slab: 由於內核會有許多小對象,這些對象構造銷燬十分頻繁,比如 i-node,dentry,這些對象如果每次構建的時候就向內存要一個頁 (4kb),而其實只有幾個字節,這樣就會非常浪費,爲了解決這個問題,就引入了一種新的機制來處理在同一個頁框中如何分配小存儲區,而 slab 可以對小對象進行分配,這樣就不用爲每一個對象分配頁框,從而節省了空間,內核對一些小對象創建析構很頻繁,slab 對這些小對象進行緩衝,可以重複利用,減少內存分配次數。

轉自:www.cnblogs.com/peida/archive/2012/12/25/2833108.html

****推薦關注「算法愛好者」,修煉編程內功

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/kCk7CboCW78KCXLRJhRcPA