vmstat 命令的用法說明
用途
報告虛擬內存統計信息。
語法
vmstat [ -f ] [ -i ] [ -s ] [ -I ] [ -t ] [ -v ] [ PhysicalVolume ... ] [ Interval [ Count ] ]
描述
vmstat 命令報告關於內核線程、虛擬內存、磁盤、陷阱和 CPU 活動的統計信息。由 vmstat 命令生成的報告可以用於平衡系統負載活動。系統範圍內的這些統計信息(所有的處理器中)都計算出以百分比表示的平均值,或者計算其總和。
如果調用 vmstat 命令時不帶標誌,則報告包含系統啓動後虛擬內存活動的摘要。如果指定 -f 標誌,則 vmstat 命令報告自從系統啓動後派生的數量。PhysicalVolume 參數指定物理卷的名稱。
Interval 參數指定每個報告之間的時間量(以秒計)。第一個報告包含系統啓動後時間的統計信息。後續報告包含自從前一個報告起的時間間隔過程中所收集的統計信息。如果沒有指定 Intervalvmstat 命令生成單個報告然後退出。Count 參數只能和 Interval 參數一起指定。如果指定了 Count 參數,其值決定生成的報告數目和相互間隔的秒數。如果 Interval 參數被指定而沒有 Count 參數,則連續生成報告。Count 參數不允許爲 0。 參數,
在 AIX 4.3.3 及更新版本包含有此方法的增強,用於計算 CPU 等待磁盤 I/O 所花時間(wio操作系統更早的版本中使用的該方法在 SMP 上會給出誇張的 wio 時間報告。 時間)的百分比。某些情況下,AIX 4.3.2 以及該
AIX 4.3.2 和更早版本中使用的方法如下:在每個處理器的每一次時鐘中斷(每個處理器一秒鐘 100 次),確定上一個 10 毫秒時間要歸入四種類別(usr/sys/wio/idle)中的哪一個。如果在時鐘中斷的時候,CPU 正忙於 usr 方式,那麼 usr 將獲取該時鐘週期添加到其類別中。如果在時鐘中斷的時候,CPU 正忙於內核方式,那麼 sys 類別獲取該時鐘週期。如果 CPU 不忙的話,則檢測是否有磁盤 I/O 正在進行。如果有任何正在進行的磁盤 I/ O,則累加 wio 類別。如果沒有磁盤 I/O 正在進行且 CPU 不忙,則 idle 類別獲取該時鐘週期。由於所有的空閒 CPU 都被歸入 wio 類別,而不管正在等待 I/O 的線程數量,所以會產生誇大的 wio 時間報告。例如,只有一個 I/O 線程的系統可能會報告 90% 以上的 wio 時間,而不管它擁有的 CPU 數量。sar(%wio)、vmstat(wa)和 iostat(% iowait)命令報告 wio 時間。
操作系統 AIX 4.3.3 及其更新版本使用的方法如下:如果一個未完成的 I/O 在空閒的 CPU 上啓動,則操作系統 AIX 4.3.3 中的更改將只把該 CPU 標記成 wio。當只有少量線程在進行 I/O 而系統其它部分是空閒的,此方法能報告低得多的 wio 時間。例如,一個有四個 CPU 和一個正在進行 I/O 的線程的系統將報告最多 25% 的 wio 時間。有 12 個 CPU 和一個正在進行 I/O 的線程的系統只報告最大爲 8% 的 wio 時間。NFS 客戶機通過 VMM 讀取/寫入,biods 在 VMM 中花費的等待 I/O 完成的時間現在報告爲 I/O 等待時間。
內核爲內核線程、調頁和中斷活動維護統計信息,vmstat 命令通過使用perfstat 內核擴展來對其進行訪問。磁盤輸入/輸出統計信息由設備驅動程序維護。對於磁盤,利用活動時間和傳送信息數量來確定平均傳送速率。活動時間的百分數根據報告期間驅動器忙的時間量來計算。
由 vmstat 命令生成的以下報告示例包含欄標題及其描述:
kthr:內核線程狀態在採樣間隔期間每秒鐘更改一次。
r | 置於運行隊列中的內核線程數目。 |
b | 置於等待隊列(等待資源、等待輸入/輸出)的內核線程數目。 |
內存:關於使用虛擬內存和實內存的信息。如果虛擬頁已經被訪問的話,虛擬頁可以被認爲是活動的。一頁爲 4096 個字節。
avm | 活動虛擬頁。 |
fre | 空閒列表的大小。
注:
大部分實內存都用作文件系統數據的高速緩存。對於保持較小的空閒列表,這是很正常的。
|
頁:關於缺頁故障和調頁活動的信息。這些是間隔的平均值,以秒爲單位給出。
re | 頁面調度程序輸入/輸出列表。 |
pi | 從調頁空間調度進的頁面。 |
po | 調出到調頁空間的頁面。 |
fr | 釋放的頁(頁面替換)。 |
sr | 通過頁替換算法掃描的頁面。 |
cy | 按頁替換算法的時鐘週期。 |
故障:採樣間隔平均每秒的捕獲和中斷率。
in | 設備中斷 |
sy | 系統調用。 |
cs | 內核線程上下文切換。 |
Cpu:CPU 使用時間故障百分比。
us | 用戶時間。 |
sy | 系統時間。 |
id | CPU 空閒時間。 |
wa | CPU 空閒時間,在此期間系統有未完成的磁盤/NFS I/O 請求。請參閱上面的詳細描述。 |
磁盤:每秒向指定物理卷提供的傳送數目,該過程在採樣間隔中發生。PhysicalVolume 參數可以用於指定一到四個名稱。每個指定驅動器的傳送統計信息按指定順序給出。該計數代表向物理設備的請求數。它並不暗示讀取或寫入的數據量。幾個邏輯請求可以組合成爲一個物理請求。
如果指定一個 -I 標誌,I/O 定向視圖將會出現以下欄目變化。
kthr | 除了欄 r 和 b之外,欄 p 也將顯示。
|
頁 | 將顯示新欄 fi 和 fo,代替 re 和 cy 欄。
|
標誌
-f | 報告從系統啓動後的派生數目。 |
-i | 顯示從系統啓動後每個設備造成的中斷數目。 |
-I | 用新的輸出欄顯示 I/O 定向視圖,p 在標題 kthr 下;欄 fi 和 fo 在標題頁面下,而不是欄下;re 和 cy 在頁標題中。 |
-s | 將總數結構中的內容寫入到標準輸出,該結構包含從系統初始化後調頁事件的絕對計數。-s-v 標誌一起使用。如下描述了這些事件: 標誌只能與
|
|
|
-t | 打印 vmstat 的每一輸出行旁邊的時間戳記。時間戳記按照 HH:MM:SS 格式顯示。
注:
如果指定了 -f、-s 或 -i 標誌,將不打印時間戳記。
|
-v | 將虛擬內存管理器維護的不同統計信息寫入標準輸出。-v 標誌只能與 -s 標誌一起使用。
|
-v | (由 -v顯示的統計信息,接上頁):
|
示例
-
要顯示引導後的統計信息摘要,請輸入:
vmstat
-
要顯示 2 秒時間間隔的 5 個摘要,請輸入:
vmstat 2 5
第一次摘要包含引導後的時間統計信息。
-
要顯示引導後包括邏輯磁盤 scdisk13 和 scdisk14 的統計信息摘要,請輸入:
vmstat scdisk13 scdisk14
-
要顯示派生統計信息,請輸入:
vmstat -f
-
要顯示各事件的計數,請輸入:
vmstat -s
-
要顯示 vmstat的每一輸出欄旁邊的時間戳記,請輸入:
vmstat -t
-
要以另一套輸出欄顯示新的 I/O 定向視圖,請輸入:
vmstat -I
-
要顯示所有可用的 VMM 統計信息,請輸入:
vmstat -vs
文件
/usr/bin/vmstat | 包含 vmstat 命令。 |
來源:http://www.eygle.com/digest/2007/07/vmstat_man_page.html
Ubuntu Linux系統下也用vmstat查看系統內存使用情況
昨天說到使用vmstat查看FreeBSD的內存真實使用情況,其實vmstat在Ubuntu LInux系統下,也是一個非常不錯的查看系統信息的命令,其顯示的信息要比top命令全的多,而且可以同時看到cpu、內存、硬盤等不同的系統資源的使用情況!
其實vmstat是Virtual Meomory Statistics(虛擬內存統計)的縮寫,可對操作系統的虛擬內存、進程、CPU活動進行監視。它是對系統的整體情況進行統計,不足之處是無法對某個進程進行深入分析。
vmstat的語法如下:
vmstat [-V] [-n] [delay [count]]
其中,-V表示打印出版本信息;-n表示在週期性循環輸出時,輸出的頭部信息僅顯示一次;delay是兩次輸出之間的延遲時間;count是指按照這個時間間隔統計的次數。對於vmstat輸出各字段的含義,可運行man vmstat查看。
[root@localhost ~]# vmstat 2 2
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 0 323016 4160 18064 0 0 11 4 1004 27 0 10 89 0
0 0 0 323016 4160 18064 0 0 0 0 53 4 0 10 90 0
下面給出了各個參數的不同含義:
procs:
r-->在運行隊列中等待的進程數
b-->在等待io的進程數
w-->可以進入運行隊列但被替換的進程
memoy
swap-->現時可用的交換內存(k表示)
free-->空閒的內存(k表示)
buff-->被用來做爲緩存的內存數,單位:KB
cache-->被用來做爲文件讀寫緩存的內存數,單位:KB
swap
si-->從磁盤交換到內存的交換頁數量,單位:KB/秒
so-->從內存交換到磁盤的交換頁數量,單位:KB/秒
IO
bi-->磁盤塊入
bo-->磁盤塊出
System
in-->每秒的中斷數,包括時鐘中斷
cs-->每秒的環境(上下文)切換次數
CPU
按 CPU 的總使用百分比來顯示
us-->用戶進程使用的時間
sy-->系統進程使用的時間
id-->cpu空閒的時間
pages
re-->回收的頁面
mf-->非嚴重錯誤的頁面
pi-->進入頁面數(k表示)
po-->出頁面數(k表示)
fr-->空餘的頁面數(k表示)
de-->提前讀入的頁面中的未命中數
sr-->通過時鐘算法掃描的頁面
disk 顯示每秒的磁盤操作。
s表示scsi盤,0表示盤號
fault 顯示每秒的中斷數
in-->設備中斷
sy-->系統中斷
cy-->cpu交換
如果fre對於page列,re,pi,po,cy維持於比較穩定的狀態,PI率不超過5,如果有pagin發生,那麼關聯頁面必須先進行 pageout在內存相對緊張的環境下pagein會強制對不同的頁面進行steal操作。如果系統正在讀一個大批的永久頁面,你也許可以看到po和pi 列會出現不一致的增長,這種情景並不一定表明系統負載過重,但是有必要對應用程序的數據訪問模式進行見檢查。在穩定的情況下,掃描率和重置率幾乎相等,在 多個進程處理使用不同的頁面的情況下,頁面會更加不穩定和雜亂,這時掃描率可能會比重置率高出。
faults列,in,sy,cs會不斷跳躍,這裏沒有明確的限制,唯一的就是這些值最少大於100 cpu列,us,sys,id和wa也是不確定的,最理想的狀態是使cpu處於100%工作狀態,但這隻適合單用戶的情況下。
如果在多用戶環境中us+sys>80,進程就會在運行隊列中花費等待時間,響應時間和吞吐量就會下降。wa>40表明磁盤io沒有也許存在不合理的平衡,或者對磁盤操作比較頻繁
如果 r經常大於 4 ,且id經常少於40,表示cpu的負荷很重。
如果pi,po 長期不等於0,表示內存不足。
如果disk 經常不等於0, 且在 b中的隊列 大於3, 表示 io性能不好。
linux命令vmstat介紹
vmstat介紹
通過STATSPACK收集服務器信息,主要通過收集VMSTAT的信息來展現服務器狀況。VMSTAT工具是最常見的UNIX監控工具,可以展現給定時間間隔的服務器的狀態值。
一般VMSTAT工具的使用是通過兩個數字參數來完成的,第一個參數是採樣的時間間隔數,單位是秒,第二個參數是採樣的次數。如:
[oracle@localhost oracle]$vmstat 2
procs ———–memory———- —swap– —–io—- –system– —-cpu—-
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 195804 3812 40616 1598656 0 0 0 0 1024 66976 0 0 100 0
0 0 195804 3812 40616 1598656 0 0 0 12 1048 66961 0 0 100 0
0 0 195804 3812 40616 1598656 0 0 0 28 1054 67067 0 0 100 0
0 0 195804 3812 40616 1598656 0 0 0 0 1020 66988 0 0 100 0
(注:目前系統幾乎空閒,並且不同操作系統VMSTAT輸出內容有所不同)
目前說來,對於服務器監控有用處的度量主要有:
r(運行隊列)
pi(頁導入)
us(用戶CPU)
sy(系統CPU)
id(空閒)
(如果r經常大於4 ,且id經常少於40,表示cpu的負荷很重。)
(如果bi,bo 長期不等於0,表示內存不足)
通過VMSTAT識別CPU瓶頸
r(運行隊列)展示了正在執行和等待CPU資源的任務個數。當這個值超過了CPU數目,就會出現CPU瓶頸了
獲得CPU個數的命令(LINUX環境):
cat /proc/cpuinfo|grep processor|wc -l
當r值超過了CPU個數,就會出現CPU瓶頸,解決辦法大體幾種:
1. 最簡單的就是增加CPU個數
2. 通過調整任務執行時間,如大任務放到系統不繁忙的情況下進行執行,進爾平衡系統任務
3. 調整已有任務的優先級
通過VMSTAT識別CPU滿負荷
首先需要聲明一點的是,vmstat中CPU的度量是百分比的。當us+sy的值接近100的時候,表示CPU正在接近滿負荷工作。但要注意的是,CPU 滿負荷工作並不能說明什麼,UNIX總是試圖要CPU儘可能的繁忙,使得任務的吞吐量最大化。唯一能夠確定CPU瓶頸的還是r(運行隊列)的值。
通過VMSTAT識別RAM瓶頸
數據庫服務器都只有有限的RAM,出現內存爭用現象是Oracle的常見問題。
首先察看RAM的數量,命令如下(LINUX環境):
[oracle@oracle-db02 ~]$ free
total used free shared buffers cached
Mem: 2074924 2071112 3812 0 40616 1598656
-/+ buffers/cache: 431840 1643084
Swap: 3068404 195804 2872600
當然可以使用top等其他命令來顯示RAM。
當內存的需求大於RAM的數量,服務器啓動了虛擬內存機制,通過虛擬內存,可以將RAM段移到SWAP DISK的特殊磁盤段上,這樣會 出現虛擬內存的頁導出和頁導入現象,頁導出並不能說明RAM瓶頸,虛擬內存系統經常會對內存段進行頁導出,但頁導入操作就表明了服務器需要更多的內存了, 頁導入需要從SWAP DISK上將內存段複製回RAM,導致服務器速度變慢。
解決的辦法有幾種:
1. 最簡單的,加大RAM
2. 改小SGA,使得對RAM需求減少
3. 減少RAM的需求(如:減少PGA)
關於vmstat,top,ps aux查看的cpu佔用率不一致的問題
問題:用vmstat,top,和ps aux三個命令查看進程對cpu的佔用率,數值差異很大。
例:
用 vmstat 查看系統cpu空閒率, id是cpu的空閒率,可以看出,空閒率一直在73%以上
用 ps aux 統計兩個compress進程的cpu佔用率,長時間恆定在15.5%和28.9%
用 top統計兩個compress進程的cpu佔用率,可以看出是一個動態變化的過程
(命令執行結果後面有顯示)
這三個命令查出的cpu利用率不統一
首先,ps aux中兩個compress進程佔用cpu 15.5%+28.9%>40%,再加上其它進程,爲
何vmstat查看cpu空閒率id還能一直大於73%
其次,top命令顯示的進程compress的cpu佔用率和ps顯示的數值差別很大,ps的
cpu佔用率雷打不動,一直是恆定值,
top的比較動態, 難道ps aux顯示的進程cpu佔用率不可靠?
最後,這三個命令查出的cpu佔用率相互之間均不統一,用哪一個更可靠?例如輸入如下命令,粗體字是cpu佔用率
$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 432 802660 28724 5747324 0 0 204 770 0 0 6 3 90 2
3 0 432 799196 28724 5747392 0 0 0 152 1455 681 2 2 96 0
0 0 432 802420 28724 5747460 0 0 0 480 1599 1892 10 8 82 0
0 0 432 802292 28724 5747664 0 0 0 440 1859 6179 14 13 73 0
2 0 432 797636 28724 5752084 0 0 0 240 1403 3419 8 7 85 0
1 0 432 798732 28724 5751268 0 0 0 448 1506 4608 10 8 81 0
2 0 432 797924 28724 5752084 0 0 0 192 1752 4332 11 10 79 0
0 0 432 802076 28724 5747936 0 0 0 280 1705 1527 14 6 79 0
$ps aux | grep compress
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
img 6569 15.5 0.2 36716 16540 ? S Aug12 230:57 ./bin/compress 8014
img 6570 28.9 0.2 54592 22524 ? S Aug12 430:28 ./bin/compress 8004
$top | grep compress
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
6569 img 16 0 40956 20m 6632 R 10.7 0.3 231:10.12 compress
6570 img 16 0 54592 21m 2456 S 20.3 0.3 430:54.32 compress
6569 img 17 0 36740 16m 2456 S 10.3 0.2 231:10.43 compress
6570 img 16 0 54592 21m 2456 R 58.9 0.3 430:56.09 compress
6569 img 16 0 36716 16m 2456 R 53.9 0.2 231:12.05 compress
6570 img 16 0 58444 24m 4752 R 69.9 0.3 430:58.19 compress
6569 img 16 0 36716 16m 2456 S 60.2 0.2 231:13.86 compress
6570 img 16 0 54592 21m 2456 S 52.6 0.3 430:59.77 compress
6569 img 15 0 36716 16m 2456 S 45.3 0.2 231:15.22 compress
大概看了些源碼,補充一下:
top,ps,vmstat都是根據系統的proc文件進行計算的,其中vmstat,top都使用了/proc/stat文件,而ps,top也使用了/proc/*/stat文件進行計算。
1.vmstat對於cpu idle的計算方式比較複雜,但是顯示的爲平均值,即使用cpu使用時間片的差值/時間間隔/cpu個數(爲物理cpu數目*cpu核心數),其中時間間隔爲vmstat後加的參數,如vmstat 10就爲10s內的平均cpu 佔用率;
2.ps計算的爲每個進程的cpu佔用時間,使用的爲/proc/*/stat文件,其中*爲進程號,計算方式爲使用cpu總的時間片數/Hertz,目前確認爲對於每個物理cpu的佔用比率,因此在雙核機器上顯示的數值需要除以核心數2;
3.top使用的是/proc/stat計算上面顯示的cpu佔用,使用/proc/*/stat計算每個進程佔用的時間。但是計算的方式有所不同,代碼較爲複雜,但是目前確認爲默認顯示爲Irix模式,即爲相對於單個cpu core的佔用的時間,如雙核機器需要將該數值除以2*2計算,通過 shift+i可以進行切換;
通過上述說明可以解釋珺方發現的問題:
問題1:首先,ps aux中兩個compress進程佔用cpu 15.5%+28.9%>40%,再加上其它進程,爲何vmstat查看cpu空閒率id還能一直大於73%
ps的cpu佔用率需要除以雙核cpu數目爲2,因此實際佔用爲(15.5%+28.9% )/2=22.2% ,也就約等於100%-73%;
問題2:其次,top命令顯示的進程compress的cpu佔用率和ps顯示的數值差別很大,ps的cpu佔用率雷打不動,一直是恆定值,top的比較動態, 難道ps aux顯示的進程cpu佔用率不可靠?
ps和top相差的數值爲2倍關係,因此顯示的佔用率相差很大,同時變化率也會較大;
問題3:最後,這三個命令查出的cpu佔用率相互之間均不統一,用哪一個更可靠?例如輸入如下命令,粗體字是cpu佔用率
這三個命令的佔用率是統一的,按照如下公式進行計算時數據是一致的:
vmstat 的100%-idle == ps的cpu佔用/cpu核心數 == top的cpu佔用/cpu核心數/物理cpu數目;
Linux下獲取CPU利用率和內存使用(C語言)
在Linux中如果要監視一個進程的運行情況,如查看它的CPU使用效率和內存使用情況,就需要從系統的 /proc目錄的讀取一些系統信息。然後分析得到結果,特別是在嵌入式中的應用程序這個功能就很重要。本文中的代碼是從top命令的源代碼分析中獲得,並 做了部分修改,在FC6+GCC4.1調試通過。從這個工程中我也獲得一些感悟。
1. Linux系統很優雅,如果在Windows中做這個功能就需要調用ActiveX控件。而在Linux中只需要讀取文本。
2.想完成什麼功能,如果不知道怎麼做,就想有沒有沒有其它的軟件有這個功能,如果有,查看它的源代碼就可以了,然後定製自己需要的功能。
3.多想多看多做,學習技術的不二法門。
top命令源代碼下載:http://www.groupsys.com/top/download.shtml
工程下載: http://www.cppblog.com/Files/dyj057/mytop.zip
下面是獲得系統CPU和內存情況的代碼:
get_system_info(info)
struct system_info * info;
{
char buffer[ 4096 + 1 ];
int fd, len;
char * p;
int i;
/* get load averages */
{
fd = open( " loadavg " , O_RDONLY);
len = read(fd, buffer, sizeof (buffer) - 1 );
close(fd);
buffer[len] = ' \0 ' ;
info -> load_avg[ 0 ] = strtod(buffer, & p);
info -> load_avg[ 1 ] = strtod(p, & p);
info -> load_avg[ 2 ] = strtod(p, & p);
p = skip_token(p); /* skip running/tasks */
p = skip_ws(p);
if ( * p)
info -> last_pid = atoi(p);
else
info -> last_pid = - 1 ;
}
/* get the cpu time info */
{
fd = open( " stat " , O_RDONLY);
len = read(fd, buffer, sizeof (buffer) - 1 );
close(fd);
buffer[len] = ' \0 ' ;
p = skip_token(buffer); /* "cpu" */
cp_time[ 0 ] = strtoul(p, & p, 0 );
cp_time[ 1 ] = strtoul(p, & p, 0 );
cp_time[ 2 ] = strtoul(p, & p, 0 );
cp_time[ 3 ] = strtoul(p, & p, 0 );
/* convert cp_time counts to percentages */
percentages( 4 , cpu_states, cp_time, cp_old, cp_diff);
}
/* get system wide memory usage */
{
char * p;
fd = open( " meminfo " , O_RDONLY);
len = read(fd, buffer, sizeof (buffer) - 1 );
close(fd);
buffer[len] = ' \0 ' ;
/* be prepared for extra columns to appear be seeking
to ends of lines */
p = buffer;
p = skip_token(p);
memory_stats[ 0 ] = strtoul(p, & p, 10 ); /* total memory */
p = strchr(p, ' \n ' );
p = skip_token(p);
memory_stats[ 1 ] = strtoul(p, & p, 10 ); /* free memory */
p = strchr(p, ' \n ' );
p = skip_token(p);
memory_stats[ 2 ] = strtoul(p, & p, 10 ); /* buffer memory */
p = strchr(p, ' \n ' );
p = skip_token(p);
memory_stats[ 3 ] = strtoul(p, & p, 10 ); /* cached memory */
for (i = 0 ; i < 8 ;i ++ ) {
p ++ ;
p = strchr(p, ' \n ' );
}
p = skip_token(p);
memory_stats[ 4 ] = strtoul(p, & p, 10 ); /* total swap */
p = strchr(p, ' \n ' );
p = skip_token(p);
memory_stats[ 5 ] = strtoul(p, & p, 10 ); /* free swap */
}
/* set arrays and strings */
info -> cpustates = cpu_states;
info -> memory = memory_stats;
}