1. top
top命令是Linux下常用的性能分析工具,能夠實時顯示系統中各個進程的資源佔用狀況,類似於Windows的任務管理器。
可以直接使用top命令後,查看%MEM的內容。可以選擇按進程查看或者按用戶查看,如想查看oracle用戶的進程內存使用情況的話可以使用如下的命令:
$ top
第一部分 系統信息欄 :
第一行(top):
“11:15:53”爲系統當前時刻;
“up 298days, 20:25”爲系統啓動後到現在的運作時間;
“4 users”爲當前登錄到系統的用戶,更確切的說是登錄到用戶的終端數 -- 同一個用戶同一時間對系統多個終端的連接將被視爲多個用戶連接到系統,這裏的用戶數也將表現爲終端的數目;
“load average”爲當前系統負載的平均值,後面的三個值分別爲1分鐘前、5分鐘前、15分鐘前進程的平均數,一般的可以認爲這個數值超過 CPU 數目時,CPU 將比較吃力的負載當前系統所包含的進程;
第二行(Tasks)任務(進程):
“59 total”爲當前系統進程總數;
“1 running”爲當前運行中的進程數;
“58 sleeping”爲當前處於等待狀態中的進程數;
“0 stoped”爲被停止的系統進程數;
“0 zombie”爲被複原的進程數;
第三行(Cpus):
分別表示了 CPU 當前的使用率;
第四行(Mem):
分別表示了內存總量、當前使用量、空閒內存量、以及緩衝使用中的內存量;
8306544k total — 物理內存總量(8GB)
7775876k used — 使用中的內存總量(7.7GB)
530668k free — 空閒內存總量(530M)
79236k buffers — 緩存的內存量 (79M)
第四行中使用中的內存總量(used)指的是現在系統內核控制的內存數,空閒內存總量(free)是內核還未納入其管控範圍的數量。
第五行(Swap):
表示類別同第四行(Mem),但此處反映着交換分區(Swap)的使用情況。通常,交換分區(Swap)被頻繁使用的情況,將被視作物理內存不足而造成的。
第二部分 進程列表欄:
各進程(任務)的狀態監控,內容解釋:
PID:進程的ID
USER:進程所有者
PR:進程的優先級別,越小越優先被執行
NI:nice值,負值表示高優先級,正值表示低優先級
VIRT:進程佔用的虛擬內存
RES:進程佔用的物理內存
SHR:進程使用的共享內存
S:進程的狀態。S表示休眠,R表示正在運行,Z表示僵死狀態,N表示該進程優先值爲負數
%CPU:進程佔用CPU的使用率
%MEM:進程使用的物理內存和總內存的百分比
TIME+:該進程啓動後佔用的總的CPU時間,即佔用CPU使用時間的累加值。
COMMAND:進程啓動命令名稱
$ top -b -n 1 > a
top結果輸出到文件
-b: 表示Batch-mode, 這樣可以發送信息到文件
-n 1: 表示輸出1個循環的信息
top -n 1 | head -n 5
顯示 top 的前面幾行
top -n 1 | grep '^Cpu'
只顯示 Cpu 那一行
2 free
下面是free的運行結果,一共有4行。爲了方便說明,我加上了列號。這樣可以把free的輸出看成一個二維數組FO(Free Output)。例如:
- FO[2][1] = 24677460
- FO[3][2] = 10321516
1 2 3 4 5 6
1 total used free shared buffers cached
2 Mem: 24677460 23276064 1401396 0 870540 12084008
3 -/+ buffers/cache: 10321516 14355944
4 Swap: 25151484 224188 24927296
free的輸出一共有四行,第四行爲交換區的信息,分別是交換的總量(total),使用量(used)和有多少空閒的交換區(free),這個比較清楚,不說太多。
free輸出地第二行和第三行是比較讓人迷惑的。這兩行都是說明內存使用情況的。第一列是總量(total),第二列是使用量(used),第三列是可用量(free)。
第一行的輸出時從操作系統(OS)來看的。也就是說,從OS的角度來看,計算機上一共有:
- 24677460KB(缺省時free的單位爲KB)物理內存,即FO[2][1];
- 在這些物理內存中有23276064KB(即FO[2][2])被使用了;
- 還用1401396KB(即FO[2][3])是可用的;
這裏得到第一個等式:
- FO[2][1] = FO[2][2] + FO[2][3]
FO[2][4]表示被幾個進程共享的內存的,現在已經deprecated,其值總是0(當然在一些系統上也可能不是0,主要取決於free命令是怎麼實現的)。
FO[2][5]表示被OS buffer住的內存。FO[2][6]表示被OS cache的內存。在有些時候buffer和cache這兩個詞經常混用。不過在一些比較低層的軟件裏是要區分這兩個詞的,看老外的洋文:
- A buffer is something that has yet to be "written" to disk.
- A cache is something that has been "read" from the disk and stored for later use.
也就是說buffer是用於存放要輸出到disk(塊設備)的數據的,而cache是存放從disk上讀出的數據。這二者是爲了提高IO性能的,並由OS管理。
Linux和其他成熟的操作系統(例如windows),爲了提高IO read的性能,總是要多cache一些數據,這也就是爲什麼FO[2][6](cached memory)比較大,而FO[2][3]比較小的原因。我們可以做一個簡單的測試:
- 釋放掉被系統cache佔用的數據;
echo 3>/proc/sys/vm/drop_caches
- 讀一個大文件,並記錄時間;
- 關閉該文件;
- 重讀這個大文件,並記錄時間;
第二次讀應該比第一次快很多。原來我做過一個BerkeleyDB的讀操作,大概要讀5G的文件,幾千萬條記錄。在我的環境上,第二次讀比第一次大概可以快9倍左右。
free輸出的第二行是從一個應用程序的角度看系統內存的使用情況。
- 對於FO[3][2],即-buffers/cache,表示應用程序認爲系統被用掉多少內存;
- 對於FO[3][3],即+buffers/cache,表示應用程序認爲系統還有多少內存;
因爲被系統cache和buffer佔用的內存可以被快速回收,所以通常FO[3][3]比FO[2][3]會大很多。
這裏還用兩個等式:
- FO[3][2] = FO[2][2] - FO[2][5] - FO[2][6]
- FO[3][3] = FO[2][3] + FO[2][5] + FO[2][6]
這二者都不難理解。
free命令由procps.*.rpm提供(在Redhat系列的OS上)。free命令的所有輸出值都是從/proc/meminfo中讀出的。
在系統上可能有meminfo(2)這個函數,它就是爲了解析/proc/meminfo的。procps這個包自己實現了meminfo()這個函數。可以下載一個procps的tar包看看具體實現,現在最新版式3.2.8。
3 vmstat
vmstat(Virtual Memory Statistics 虛擬內存統計) 命令用來顯示Linux系統虛擬內存狀態,也可以報告關於進程、內存、I/O等系統整體運行狀態。
3.1使用此命令,執行的vmstat每隔2秒鐘執行一次,執行6次後自動停止。
- [root@tecmint ~]# vmstat 2 6
3.2用vmstat -s參數來顯示各種事件計數器和內存統計信息。
[tecmint@tecmint ~]$ vmstat -s
1030800 total memory
524656 used memory
277784 active memory
185920 inactive memory
506144 free memory
26864 buffer memory
310104 swap cache
2064376 total swap
0 used swap
2064376 free swap
4539 non-nice user cpu ticks
0 nice user cpu ticks
11569 system cpu ticks
329608 idle cpu ticks
5012 IO-wait cpu ticks
79 IRQ cpu ticks
74 softirq cpu ticks
0 stolen cpu ticks
336038 pages paged in
67945 pages paged out
0 pages swapped in
0 pages swapped out
258526 interrupts
392439 CPU context switches
1346574857 boot time
2309 forks
注:這些信息的分別來自於/proc/meminfo,/proc/stat和/proc/vmstat。/proc/stat 中CPU 數據信息,單位是ticks。內核中有個全局變量jiffies ,來記錄系 統啓動以來,經歷的ticks 數量。ticks(滴答)就是系統時鐘中斷的時間間隔,該值與內核中HZ值有關,即ticks = 1/HZ。在時鐘中斷程序中,更新CPU 利用信息,即每個ticks 更新一次。