• 正文
    • 0. 引言:
    • 一、free命令
    • 二、vmstat 指令
    • 三、/proc/meminfo
    • 四、top 指令
    • 舉例
    • 五、htop 指令
    • 六、查看制定進程的內(nèi)存
    • 總結(jié):
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

Linux內(nèi)存占用分析的幾個方法,你知道幾個?

01/24 14:56
2011
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

0. 引言:

系統(tǒng)內(nèi)存是硬件系統(tǒng)中必不可少的部分,定時查看系統(tǒng)內(nèi)存資源運行情況,可以幫助我們及時發(fā)現(xiàn)內(nèi)存資源是否存在異常占用,確保業(yè)務(wù)的穩(wěn)定運行。

例如:定期查看公司的網(wǎng)站服務(wù)器內(nèi)存使用情況,可以確保服務(wù)器的資源是否夠用,或者發(fā)現(xiàn)服務(wù)器內(nèi)存被占用異??梢约皶r解決,避免因內(nèi)存不夠?qū)е聼o法訪問網(wǎng)站或訪問速度慢的問題。

因此,對于 Linux 管理員來說,在日常工作中能夠熟練在 Linux 系統(tǒng)下檢查內(nèi)存的運行狀況就變得尤為重要!

查看內(nèi)存的運行狀態(tài)并非難事,但是針對不同的情況使用正確的方式查看呢?

一口君整理了幾個 個非常實用的 Linux 內(nèi)存查看方法

    1、free命令2、 vmstat命令3、 /proc/meminfo 命令4、 top命令5、 htop 命令6、查看進程內(nèi)存信息

Linux內(nèi)存總覽圖

該圖很好的描述了OS內(nèi)存的使用和分配等詳細(xì)信息。建議大家配合該圖來一起學(xué)習(xí)和理解內(nèi)存的一些概念。

一、free命令

free 命令可以顯示當(dāng)前系統(tǒng)未使用的和已使用的內(nèi)存數(shù)目,還可以顯示被內(nèi)核使用的內(nèi)存緩沖區(qū)。

1. free 命令語法:

free?[options]

free 命令選項:

-b?#?以Byte為單位顯示內(nèi)存使用情況;
-k?#?以KB為單位顯示內(nèi)存使用情況;
-m?#?以MB為單位顯示內(nèi)存使用情況;
-g?#?以GB為單位顯示內(nèi)存使用情況。?
-o?#?不顯示緩沖區(qū)調(diào)節(jié)列;
-s<間隔秒數(shù)>?#?持續(xù)觀察內(nèi)存使用狀況;
-t?#?顯示內(nèi)存總和列;
-V?#?顯示版本信息。

2. free 命令實例

free?-t????#?以總和的形式顯示內(nèi)存的使用信息
free?-h?-s?10?#?周期性的查詢內(nèi)存使用信息,每10s?執(zhí)行一次命令

free?-h?-c?10?#輸出10次
??在版本 v3.2.8,就是輸出一次!需要配合?-s 使用。
??在版本 v3.3.10,不加-s,就默認(rèn)1秒輸出一次。
free?-V?#查看版本號

v3.2.8

v3.3.10

下面先解釋一下輸出的內(nèi)容:

內(nèi)容 含義
Mem 行(第二行)是內(nèi)存的使用情況
Swap 行(第三行)是交換空間的使用情況
total 總可用物理內(nèi)存。一般是總物理內(nèi)存除去一些預(yù)留的和操作系統(tǒng)本身的內(nèi)存占用,是操作系統(tǒng)可以支配的內(nèi)存大小。這個在v3.2.8和v3.3.10一樣。這個值是/proc/meminfo中MemTotal的值。
used 列顯示已經(jīng)被使用的物理內(nèi)存和交換空間。在v3.2.8,這個值是(total - free)得出來的??梢哉f是系統(tǒng)已經(jīng)被系統(tǒng)分配,但是實際并不一定正在被真正的使用,其空間可以被回收再分配的。在v3.3.10,這個值是(total - free - cache - buffers)得出來的,是真正目前正在被使用的內(nèi)存。
free 系統(tǒng)還未使用的物理內(nèi)存。這個值是/proc/meminfo中MemFree的值
shared 共享內(nèi)存的空間。這個值是/proc/meminfo中Shmem的值
buff/cache 列顯示被 buffer 和 cache 使用的物理內(nèi)存大小
available v3.3.10中的項。看起來這個值是可以使用的內(nèi)存,不過(available + used) < total,也就是available < (free + cache + buffers)。而在v3.2.8中(free + cache + buffers)是一般認(rèn)為的可用內(nèi)存,既然在新版本中有這個available數(shù)據(jù),應(yīng)該是更準(zhǔn)確的吧。畢竟并不是所有的未使用的內(nèi)存就一定是可用的。這個值是取的/proc/meminfo中MemAvailable的值,如果meminfo中沒有這個值,會依據(jù)meminfo中的Active(file),Inactive(file),MemFree,SReclaimable等值計算一個。
-/+ buffers/cache v3.2.8有這一行,v3.3.10 沒有。其中,used 這一項是(used - buffers - cached)的值,即(total - free - buffers - cached)的值,是真正在使用的內(nèi)存的值。free 這一項是(free + buffers + cached)的值,是真正未使用的內(nèi)存的值。個人覺得有 -/+ buffers/cache,這一欄看的挺習(xí)慣。。不過新版本v3.3.10的used更明確。相信有不少人和我一樣,剛看到v3.2.8里面的used占了這么多內(nèi)存的時候,有點摸不著頭腦。

二、vmstat 指令

vmstat命令是最常見的Linux/Unix監(jiān)控工具,用于查看系統(tǒng)的內(nèi)存存儲信息,是一個報告虛擬內(nèi)存統(tǒng)計信息的小工具,屬于sysstat包。

vmstat 命令報告包括:進程、內(nèi)存、分頁、阻塞 IO、中斷、磁盤、CPU

可以展現(xiàn)給定時間間隔的服務(wù)器的狀態(tài)值,包括服務(wù)器的CPU使用率,內(nèi)存使用,虛擬內(nèi)存交換情況,IO讀寫情況。

這個命令是我查看Linux/Unix最喜愛的命令,一個是Linux/Unix都支持,二是相比top,我可以看到整個機器的CPU,內(nèi)存,IO的使用情況,而不是單單看到各個進程的CPU使用率和內(nèi)存使用率(使用場景不一樣)。

1. 命令格式:

vmstat?-s(參數(shù))

2. 舉例

一般vmstat工具的使用是通過兩個數(shù)字參數(shù)來完成的,第一個參數(shù)是采樣的時間間隔數(shù),單位是秒,第二個參數(shù)是采樣的次數(shù),如:

?root@local:~#?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表示每個兩秒采集一次服務(wù)器狀態(tài),1表示只采集一次。

實際上,在應(yīng)用過程中,我們會在一段時間內(nèi)一直監(jiān)控,不想監(jiān)控直接結(jié)束vmstat就行了,例如:這表示vmstat每2秒采集數(shù)據(jù),按下ctrl + c結(jié)束程序,這里采集了3次數(shù)據(jù)我就結(jié)束了程序。

類別 項目 含義 說明
Procs(進程) r 等待執(zhí)行的任務(wù)數(shù) 展示了正在執(zhí)行和等待cpu資源的任務(wù)個數(shù)。當(dāng)這個值超過了cpu個數(shù),就會出現(xiàn)cpu瓶頸。
B 等待IO的進程數(shù)量
Memory(內(nèi)存) swpd 正在使用虛擬的內(nèi)存大小,單位k
free 空閑內(nèi)存大小
buff 已用的buff大小,對塊設(shè)備的讀寫進行緩沖
cache 已用的cache大小,文件系統(tǒng)的cache
inact 非活躍內(nèi)存大小,即被標(biāo)明可回收的內(nèi)存,區(qū)別于free和active 具體含義見:概念補充(當(dāng)使用-a選項時顯示)
active 活躍的內(nèi)存大小 具體含義見:概念補充(當(dāng)使用-a選項時顯示)
Swap si 每秒從交換區(qū)寫入內(nèi)存的大?。▎挝唬簁b/s)
so 每秒從內(nèi)存寫到交換區(qū)的大小
IO bi 每秒讀取的塊數(shù)(讀磁盤) 塊設(shè)備每秒接收的塊數(shù)量,單位是block,這里的塊設(shè)備是指系統(tǒng)上所有的磁盤和其他塊設(shè)備,現(xiàn)在的Linux版本塊的大小為1024bytes
bo 每秒寫入的塊數(shù)(寫磁盤) 塊設(shè)備每秒發(fā)送的塊數(shù)量,單位是block
system in 每秒中斷數(shù),包括時鐘中斷 這兩個值越大,會看到由內(nèi)核消耗的cpu時間sy會越多

 

秒上下文切換次數(shù),例如我們調(diào)用系統(tǒng)函數(shù),就要進行上下文切換,線程的切換,也要進程上下文切換,這個值要越小越好,太大了,要考慮調(diào)低線程或者進程的數(shù)目

cs 每秒上下文切換數(shù)
CPU(以百分比表示) us 用戶進程執(zhí)行消耗cpu時間(user time) us的值比較高時,說明用戶進程消耗的cpu時間多,但是如果長期超過50%的使用,那么我們就該考慮優(yōu)化程序算法或其他措施了
sy 系統(tǒng)進程消耗cpu時間(system time) sys的值過高時,說明系統(tǒng)內(nèi)核消耗的cpu資源多,這個不是良性的表現(xiàn),我們應(yīng)該檢查原因。這里us + sy的參考值為80%,如果us+sy 大于 80%說明可能存在CPU不足
Id 空閑時間(包括IO等待時間) 一般來說 us+sy+id=100
wa 等待IO時間 wa過高時,說明io等待比較嚴(yán)重,這可能是由于磁盤大量隨機訪問造成的,也有可能是磁盤的帶寬出現(xiàn)瓶頸。

3. 常見問題處理

常見問題及解決方法

    如果r經(jīng)常大于4,且id經(jīng)常少于40,表示cpu的負(fù)荷很重。如果pi,po長期不等于0,表示內(nèi)存不足。如果disk經(jīng)常不等于0,且在b中的隊列大于3,表示io性能不好。
    1.如果在processes中運行的序列(process r)是連續(xù)的大于在系統(tǒng)中的CPU的個數(shù)表示系統(tǒng)現(xiàn)在運行比較慢,有多數(shù)的進程等待CPU。2.如果r的輸出數(shù)大于系統(tǒng)中可用CPU個數(shù)的4倍的話,則系統(tǒng)面臨著CPU短缺的問題,或者是CPU的速率過低,系統(tǒng)中有多數(shù)的進程在等待CPU,造成系統(tǒng)中進程運行過慢。3.如果空閑時間(cpu id)持續(xù)為0并且系統(tǒng)時間(cpu sy)是用戶時間的兩倍(cpu us)系統(tǒng)則面臨著CPU資源的短缺。

當(dāng)發(fā)生以上問題的時候請先調(diào)整應(yīng)用程序對CPU的占用情況.使得應(yīng)用程序能夠更有效的使用CPU.同時可以考慮增加更多的CPU. ?關(guān)于CPU的使用情況還可以結(jié)合mpstat, ?ps aux top ?prstat –a等等一些相應(yīng)的命令來綜合考慮關(guān)于具體的CPU的使用情況,和那些進程在占用大量的CPU時間.一般情況下,應(yīng)用程序的問題會比較大一些.比如一些sql語句不合理等等都會造成這樣的現(xiàn)象.

4. 內(nèi)存問題現(xiàn)象:

內(nèi)存的瓶頸是由scan rate (sr)來決定的.scan rate是通過每秒的始終算法來進行頁掃描的.如果scan rate(sr)連續(xù)的大于每秒200頁則表示可能存在內(nèi)存缺陷.同樣的如果page項中的pi和po這兩欄表示每秒頁面的調(diào)入的頁數(shù)和每秒調(diào)出的頁數(shù).如果該值經(jīng)常為非零值,也有可能存在內(nèi)存的瓶頸,當(dāng)然,如果個別的時候不為0的話,屬于正常的頁面調(diào)度這個是虛擬內(nèi)存的主要原理.

解決辦法:

    1.調(diào)節(jié)applications & servers使得對內(nèi)存和cache的使用更加有效.2.增加系統(tǒng)的內(nèi)存.3.Implement priority paging in s in pre solaris 8 versions by adding line "set priority paging=1" in /etc/system. Remove this line if upgrading from Solaris 7 to 8 & retaining old /etc/system file.

關(guān)于內(nèi)存的使用情況還可以結(jié)ps aux top ?prstat –a等等一些相應(yīng)的命令來綜合考慮關(guān)于具體的內(nèi)存的使用情況,和那些進程在占用大量的內(nèi)存.

一般情況下,如果內(nèi)存的占用率比較高,但是,CPU的占用很低的時候,可以考慮是有很多的應(yīng)用程序占用了內(nèi)存沒有釋放,但是,并沒有占用CPU時間,可以考慮應(yīng)用程序,對于未占用CPU時間和一些后臺的程序,釋放內(nèi)存的占用。

r 表示運行隊列(就是說多少個進程真的分配到CPU),我測試的服務(wù)器目前CPU比較空閑,沒什么程序在跑,當(dāng)這個值超過了CPU數(shù)目,就會出現(xiàn)CPU瓶頸了。

這個也和top的負(fù)載有關(guān)系,一般負(fù)載超過了3就比較高,超過了5就高,超過了10就不正常了,服務(wù)器的狀態(tài)很危險。

top的負(fù)載類似每秒的運行隊列。如果運行隊列過大,表示你的CPU很繁忙,一般會造成CPU使用率很高。

5. 常見性能問題分析

IO/CPU/men連鎖反應(yīng)

1.free急劇下降
2.buff和cache被回收下降,但也無濟于事
3.依舊需要使用大量swap交換分區(qū)swpd
4.等待進程數(shù),b增多
5.讀寫IO,bi?bo增多
6.si?so大于0開始從硬盤中讀取
7.cpu等待時間用于?IO等待,wa增加

內(nèi)存不足

1.開始使用swpd,swpd不為0
2.si?so大于0開始從硬盤中讀取

io瓶頸

1.讀寫IO,bi?bo增多超過2000
2.cpu等待時間用于?IO等待,wa增加?超過20
3.sy?系統(tǒng)調(diào)用時間長,IO操作頻繁會導(dǎo)致增加?>30%
4.wa?io等待時間長
????iowait%?<20%????????????良好
????iowait%?<35%????????????一般
????iowait%?>50%
5.進一步使用iostat觀察

CPU瓶頸:load,vmstat中r列

????1.反應(yīng)為CPU隊列長度
??? 2.一段時間內(nèi),CPU正在處理和等待CPU處理的進程數(shù)之和,直接反應(yīng)了CPU的使用和申請情況。
??? 3.理想的load average:核數(shù)*CPU數(shù)*0.7
??????? CPU個數(shù):grep 'physical?id'?/proc/cpuinfo?|?sort?-u
????????核數(shù):grep 'core?id'?/proc/cpuinfo?|?sort?-u?|?wc?-l
????4.超過這個值就說明已經(jīng)是CPU瓶頸了

三、/proc/meminfo

用途:用于從/proc文件系統(tǒng)中提取與內(nèi)存相關(guān)的信息。這些文件包含有 系統(tǒng)和內(nèi)核的內(nèi)部信息。其實 free 命令中的信息都來自于 /proc/meminfo 文件。/proc/meminfo 文件包含了更多更原始的信息,只是看起來不太直觀。

1. 查看方法:

cat?/proc/meminfo

2. 實例及信息解釋

peng@ubuntu:~$?cat?/proc/meminfo
MemTotal:????????2017504?kB?//所有可用的內(nèi)存大小,
物理內(nèi)存減去預(yù)留位和內(nèi)核使用。系統(tǒng)從加電開始到引導(dǎo)完成,firmware/BIOS要預(yù)留一
些內(nèi)存,內(nèi)核本身要占用一些內(nèi)存,最后剩下可供內(nèi)核支配的內(nèi)存就是MemTotal。這個值
在系統(tǒng)運行期間一般是固定不變的,重啟會改變。
MemFree:????????? 511052 kB //表示系統(tǒng)尚未使用的內(nèi)存。
MemAvailable:?????640336?kB?//真正的系統(tǒng)可用內(nèi)存,
系統(tǒng)中有些內(nèi)存雖然已被使用但是可以回收的,比如cache/buffer、slab都有一部分可
以回收,所以這部分可回收的內(nèi)存加上MemFree才是系統(tǒng)可用的內(nèi)存
Buffers:??????????114348?kB?//用來給塊設(shè)備做緩存的內(nèi)存,(文件系統(tǒng)的?metadata、pages)
Cached:???????????162264?kB?//分配給文件緩沖區(qū)的內(nèi)存,例如vi一個文件,就會將未保存的內(nèi)容寫到該緩沖區(qū)
SwapCached:?????????3032?kB?//被高速緩沖存儲用的交換空間(硬盤的swap)的大小
Active:???????????555484?kB?//經(jīng)常使用的高速緩沖存儲器頁面文件大小
Inactive:?????????295984?kB?//不經(jīng)常使用的高速緩沖存儲器文件大小
Active(anon):?????381020?kB?//活躍的匿名內(nèi)存
Inactive(anon):???244068?kB?//不活躍的匿名內(nèi)存
Active(file):?????174464?kB?//活躍的文件使用內(nèi)存
Inactive(file):????51916?kB?//不活躍的文件使用內(nèi)存
Unevictable:??????????48?kB?//不能被釋放的內(nèi)存頁
Mlocked:??????????????48?kB?//系統(tǒng)調(diào)用?mlock?
SwapTotal:????????998396?kB?//交換空間總內(nèi)存
SwapFree:?????????843916?kB?//交換空間空閑內(nèi)存
Dirty:???????????????128?kB?//等待被寫回到磁盤的
Writeback:?????????????0?kB?//正在被寫回的
AnonPages:????????572776?kB?//未映射頁的內(nèi)存/映射到用戶空間的非文件頁表大小
Mapped:???????????119816?kB?//映射文件內(nèi)存
Shmem:?????????????50212?kB?//已經(jīng)被分配的共享內(nèi)存
Slab:?????????????113700?kB??//內(nèi)核數(shù)據(jù)結(jié)構(gòu)緩存
SReclaimable:??????68652?kB?//可收回slab內(nèi)存
SUnreclaim:????????45048?kB?//不可收回slab內(nèi)存
KernelStack:????????8812?kB?//內(nèi)核消耗的內(nèi)存
PageTables:????????27428?kB?//管理內(nèi)存分頁的索引表的大小
NFS_Unstable:??????????0?kB?//不穩(wěn)定頁表的大小
Bounce:????????????????0?kB?//在低端內(nèi)存中分配一個臨時buffer作為跳轉(zhuǎn),把位
于高端內(nèi)存的緩存數(shù)據(jù)復(fù)制到此處消耗的內(nèi)存
WritebackTmp:??????????0?kB?//FUSE用于臨時寫回緩沖區(qū)的內(nèi)存
CommitLimit:?????2007148?kB?//系統(tǒng)實際可分配內(nèi)存
Committed_AS:????3567280?kB?//系統(tǒng)當(dāng)前已分配的內(nèi)存
VmallocTotal:???34359738367?kB?//預(yù)留的虛擬內(nèi)存總量
VmallocUsed:???????????0?kB?//已經(jīng)被使用的虛擬內(nèi)存
VmallocChunk:??????????0?kB?//可分配的最大的邏輯連續(xù)的虛擬內(nèi)存
HardwareCorrupted:?????0?kB?//表示“中毒頁面”中的內(nèi)存量
即has?failed的內(nèi)存(通常由ECC標(biāo)記).?ECC代表“糾錯碼”.?ECC?memory能夠糾正小錯誤并檢測較大錯誤;
在具有非ECC內(nèi)存的典型PC上,內(nèi)存錯誤未被檢測到.如果使用ECC檢測到無法糾正的錯誤(在內(nèi)存或緩存中,
具體取決于系統(tǒng)的硬件支持),則Linux內(nèi)核會將相應(yīng)的頁面標(biāo)記為中毒.
AnonHugePages:?????????0?kB?//匿名大頁
【/proc/meminfo的AnonHugePages==所有進程的/proc/<pid>/smaps中AnonHugePages之和】
ShmemHugePages:????????0?kB??//用于共享內(nèi)存的大頁
ShmemPmdMapped:????????0?kB
CmaTotal:??????????????0?kB?//連續(xù)內(nèi)存區(qū)管理總量
CmaFree:???????????????0?kB?//連續(xù)內(nèi)存區(qū)管理空閑量
HugePages_Total:???????0????//預(yù)留HugePages的總個數(shù)
HugePages_Free:????????0????//池中尚未分配的?HugePages?數(shù)量,
真正空閑的頁數(shù)等于HugePages_Free?-?HugePages_Rsvd
HugePages_Rsvd:????????0????//表示池中已經(jīng)被應(yīng)用程序分配但尚未使用的?HugePages?數(shù)量
HugePages_Surp:????????0????//這個值得意思是當(dāng)開始配置了20個大頁,現(xiàn)在修改配置為16,那么這個參數(shù)就會顯示為4,一般不修改配置,這個值都是0
Hugepagesize:???????2048?kB?//大內(nèi)存頁的size
//指直接映射(direct?mapping)的內(nèi)存大小,從代碼上來看,值記錄管理頁表占用的內(nèi)存,就是描述線性映射空間中,有多個空間分別使用了2M/4K/1G頁映射
DirectMap4k:???????96128?kB
DirectMap2M:?????2000896?kB?
DirectMap1G:???????????0?kB
    注意這個文件顯示的單位是kB而不是KB,1kB=1000B,但是實際上應(yīng)該是KB,1KB=1024B還可以使用命令 less /proc/meminfo 直接讀取該文件。通過使用 less 命令,可以在長長的輸出中向上和向下滾動,找到你需要的內(nèi)容。

從中我們可以很清晰明了的看出內(nèi)存中的各種指標(biāo)情況,例如 MemFree的空閑內(nèi)存和SwapFree中的交換內(nèi)存。

3. 代碼實例

負(fù)責(zé)輸出/proc/meminfo的源代碼是:

fs/proc/meminfo.c?:?meminfo_proc_show()
static?int?meminfo_proc_show(struct?seq_file?*m,?void?*v)
{
?struct?sysinfo?i;
?unsigned?long?committed;
?long?cached;
?long?available;
?unsigned?long?pages[NR_LRU_LISTS];
?int?lru;
?
?si_meminfo(&i);
?si_swapinfo(&i);
?committed?=?percpu_counter_read_positive(&vm_committed_as);
?
?cached?=?global_node_page_state(NR_FILE_PAGES)?-
???total_swapcache_pages()?-?i.bufferram;
?if?(cached?<?0)
??cached?=?0;
?
?for?(lru?=?LRU_BASE;?lru?<?NR_LRU_LISTS;?lru++)
??pages[lru]?=?global_node_page_state(NR_LRU_BASE?+?lru);
?
?available?=?si_mem_available();
?
?show_val_kb(m,?"MemTotal:???????",?i.totalram);
?show_val_kb(m,?"MemFree:????????",?i.freeram);
?show_val_kb(m,?"MemAvailable:???",?available);
?show_val_kb(m,?"Buffers:????????",?i.bufferram);
?show_val_kb(m,?"Cached:?????????",?cached);
?show_val_kb(m,?"SwapCached:?????",?total_swapcache_pages());
?show_val_kb(m,?"Active:?????????",?pages[LRU_ACTIVE_ANON]?+
????????pages[LRU_ACTIVE_FILE]);
?show_val_kb(m,?"Inactive:???????",?pages[LRU_INACTIVE_ANON]?+
????????pages[LRU_INACTIVE_FILE]);
?show_val_kb(m,?"Active(anon):???",?pages[LRU_ACTIVE_ANON]);
?show_val_kb(m,?"Inactive(anon):?",?pages[LRU_INACTIVE_ANON]);
?show_val_kb(m,?"Active(file):???",?pages[LRU_ACTIVE_FILE]);
?show_val_kb(m,?"Inactive(file):?",?pages[LRU_INACTIVE_FILE]);
?show_val_kb(m,?"Unevictable:????",?pages[LRU_UNEVICTABLE]);
?show_val_kb(m,?"Mlocked:????????",?global_zone_page_state(NR_MLOCK));
?
#ifdef?CONFIG_HIGHMEM
?show_val_kb(m,?"HighTotal:??????",?i.totalhigh);
?show_val_kb(m,?"HighFree:???????",?i.freehigh);
?show_val_kb(m,?"LowTotal:???????",?i.totalram?-?i.totalhigh);
?show_val_kb(m,?"LowFree:????????",?i.freeram?-?i.freehigh);
#endif
?
#ifndef?CONFIG_MMU
?show_val_kb(m,?"MmapCopy:???????",
??????(unsigned?long)atomic_long_read(&mmap_pages_allocated));
#endif
?
?show_val_kb(m,?"SwapTotal:??????",?i.totalswap);
?show_val_kb(m,?"SwapFree:???????",?i.freeswap);
?show_val_kb(m,?"Dirty:??????????",
??????global_node_page_state(NR_FILE_DIRTY));
?show_val_kb(m,?"Writeback:??????",
??????global_node_page_state(NR_WRITEBACK));
?show_val_kb(m,?"AnonPages:??????",
??????global_node_page_state(NR_ANON_MAPPED));
?show_val_kb(m,?"Mapped:?????????",
??????global_node_page_state(NR_FILE_MAPPED));
?show_val_kb(m,?"Shmem:??????????",?i.sharedram);
?show_val_kb(m,?"Slab:???????????",
??????global_node_page_state(NR_SLAB_RECLAIMABLE)?+
??????global_node_page_state(NR_SLAB_UNRECLAIMABLE));
?
?show_val_kb(m,?"SReclaimable:???",
??????global_node_page_state(NR_SLAB_RECLAIMABLE));
?show_val_kb(m,?"SUnreclaim:?????",
??????global_node_page_state(NR_SLAB_UNRECLAIMABLE));
?seq_printf(m,?"KernelStack:????%8lu?kBn",
?????global_zone_page_state(NR_KERNEL_STACK_KB));
?show_val_kb(m,?"PageTables:?????",
??????global_zone_page_state(NR_PAGETABLE));
#ifdef?CONFIG_QUICKLIST
?show_val_kb(m,?"Quicklists:?????",?quicklist_total_size());
#endif
?
?show_val_kb(m,?"NFS_Unstable:???",
??????global_node_page_state(NR_UNSTABLE_NFS));
?show_val_kb(m,?"Bounce:?????????",
??????global_zone_page_state(NR_BOUNCE));
?show_val_kb(m,?"WritebackTmp:???",
??????global_node_page_state(NR_WRITEBACK_TEMP));
?show_val_kb(m,?"CommitLimit:????",?vm_commit_limit());
?show_val_kb(m,?"Committed_AS:???",?committed);
?seq_printf(m,?"VmallocTotal:???%8lu?kBn",
?????(unsigned?long)VMALLOC_TOTAL?>>?10);
?show_val_kb(m,?"VmallocUsed:????",?0ul);
?show_val_kb(m,?"VmallocChunk:???",?0ul);
?
#ifdef?CONFIG_MEMORY_FAILURE
?seq_printf(m,?"HardwareCorrupted:?%5lu?kBn",
?????atomic_long_read(&num_poisoned_pages)?<<?(PAGE_SHIFT?-?10));
#endif
?
#ifdef?CONFIG_TRANSPARENT_HUGEPAGE
?show_val_kb(m,?"AnonHugePages:??",
??????global_node_page_state(NR_ANON_THPS)?*?HPAGE_PMD_NR);
?show_val_kb(m,?"ShmemHugePages:?",
??????global_node_page_state(NR_SHMEM_THPS)?*?HPAGE_PMD_NR);
?show_val_kb(m,?"ShmemPmdMapped:?",
??????global_node_page_state(NR_SHMEM_PMDMAPPED)?*?HPAGE_PMD_NR);
#endif
?
#ifdef?CONFIG_CMA
?show_val_kb(m,?"CmaTotal:???????",?totalcma_pages);
?show_val_kb(m,?"CmaFree:????????",
??????global_zone_page_state(NR_FREE_CMA_PAGES));
#endif
?
?hugetlb_report_meminfo(m);
?
?arch_report_meminfo(m);
?
?return?0;
}

四、top 指令

用途:用于打印系統(tǒng)中的CPU和內(nèi)存使用情況。輸出結(jié)果中,可以很清晰的看出已用和可用內(nèi)存的資源情況。top 最好的地方之一就是發(fā)現(xiàn)可能已經(jīng)失控的服務(wù)的進程 ID 號(PID)。有了這些 PID,你可以對有問題的任務(wù)進行故障排除(或 kill)。

語法

top?[-]?[d?delay]?[q]?[c]?[S]?[s]?[i]?[n]?[b]

參數(shù)說明:

d?:?改變顯示的更新速度,或是在交談式指令列(?interactive?command)按?s
q?:?沒有任何延遲的顯示速度,如果使用者是有?superuser?的權(quán)限,則?top?將會以最高的優(yōu)先序執(zhí)行
c?:?切換顯示模式,共有兩種模式,一是只顯示執(zhí)行檔的名稱,另一種是顯示完整的路徑與名稱
S?:?累積模式,會將己完成或消失的子進程?(?dead?child?process?)?的?CPU?time?累積起來
s?:?安全模式,將交談式指令取消,?避免潛在的危機
i?:?不顯示任何閑置?(idle)?或無用?(zombie)?的進程
n?:?更新的次數(shù),完成后將會退出?top
b?:?批次檔模式,搭配?"n"?參數(shù)一起使用,可以用來將?top?的結(jié)果輸出到檔案內(nèi)

舉例

第一行,任務(wù)隊列信息,同 uptime 命令的執(zhí)行結(jié)果

系統(tǒng)時間:02:19:10
運行時間:up 2:26 min,
當(dāng)前登錄用戶:1 user
負(fù)載均衡(uptime) ?load average: 0.00, 0.06, 0.07
average后面的三個數(shù)分別是1分鐘、5分鐘、15分鐘的負(fù)載情況。load average數(shù)據(jù)是每隔5秒鐘檢查一次活躍的進程數(shù),然后按特定算法計算出的數(shù)值。如果這個數(shù)除以邏輯CPU的數(shù)量,結(jié)果高于5的時候就表明系統(tǒng)在超負(fù)荷運轉(zhuǎn)了

第二行,Tasks — 任務(wù)(進程)

總進程:229 total, 運行:1 running, 休眠:163 sleeping, 停止: 0 stopped, 僵尸進程: 0 zombie

第三行,cpu狀態(tài)信息

0.7%us【user space】— 用戶空間占用CPU的百分比。1.0%sy【sysctl】— 內(nèi)核空間占用CPU的百分比。0.0%ni【】— 改變過優(yōu)先級的進程占用CPU的百分比
97.9%id【idolt】— 空閑CPU百分比
0.3%wa【wait】— IO等待占用CPU的百分比
0.0%hi【Hardware IRQ】— 硬中斷占用CPU的百分比
0.0%si【Software Interrupts】— 軟中斷占用CPU的百分比

第四行,內(nèi)存狀態(tài)

2017504 total, ? 653616 free, ?1154200 used, ? 209688 buff/cache【緩存的內(nèi)存量】

第五行,swap交換分區(qū)信息

998396 total, ? 771068 free, ? 227328 used. ? 635608 avail Mem

第七行以下:各進程(任務(wù))的狀態(tài)監(jiān)控

PID — 進程id
USER — 進程所有者
PR — 進程優(yōu)先級
NI — nice值。負(fù)值表示高優(yōu)先級,正值表示低優(yōu)先級
VIRT — 進程使用的虛擬內(nèi)存總量,單位kb。VIRT=SWAP+RES
RES — 進程使用的、未被換出的物理內(nèi)存大小,單位kb。RES=CODE+DATA
SHR — 共享內(nèi)存大小,單位kb
S —進程狀態(tài)。D=不可中斷的睡眠狀態(tài) R=運行 S=睡眠 T=跟蹤/停止 Z=僵尸進程
%CPU — 上次更新到現(xiàn)在的CPU時間占用百分比
%MEM — 進程使用的物理內(nèi)存百分比
TIME+ — 進程使用的CPU時間總計,單位1/100秒
COMMAND — 進程名稱(命令名/命令行)

常用實例

    顯示進程信息
#?top
    顯示完整命令
#?top?-c
    以批處理模式顯示程序信息
#?top?-b
    以累積模式顯示程序信息
#?top?-S
    設(shè)置信息更新次數(shù)
top?-n?2

//表示更新兩次后終止更新顯示

    設(shè)置信息更新時間
#?top?-d?3

//表示更新周期為3秒

    顯示指定的進程信息
#?top?-p?139

//顯示進程號為139的進程信息,CPU、內(nèi)存占用率等

    顯示更新十次后退出
top?-n?10

五、htop 指令

htop 它類似于 top 命令,但可以讓你在垂直和水平方向上滾動,所以你可以看到系統(tǒng)上運行的所有進程,以及他們完整的命令行。

可以不用輸入進程的 PID 就可以對此進程進行相關(guān)的操作 (killing, renicing)。

htop快照:可以使用快捷鍵

F1,h,?:查看htop使用說明,
F2,s??:設(shè)置選項
F3,/??:搜索進程
F4,??:過濾器,輸入關(guān)鍵字搜索
F5,t??:顯示屬性結(jié)構(gòu)
F6,<,>:選擇排序方式
F7,?[,:減少進程的優(yōu)先級(nice)
F8,]?:增加進程的優(yōu)先級(nice)
F9,k?:殺掉選中的進程
F10,q:退出htop
u:顯示所有用戶,并可以選中某一特定用戶的進程
U:取消標(biāo)記所有的進程

第1行-第4行:顯示CPU當(dāng)前的運行負(fù)載,有幾核就有幾行,我的是1核

Mem:顯示內(nèi)存的使用情況,3887M大概是3.8G,此時的Mem不包含buffers和cached的內(nèi)存,所以和free -m會不同Swp:顯示交換空間的使用情況,交換空間是當(dāng)內(nèi)存不夠和其中有一些長期不用的數(shù)據(jù)時,ubuntu會把這些暫時放到交換空間中

其他信息可以參考top命令說明。

PS:如果你終端沒安裝 htop,先通過指令來安裝。sudo apt-get update
sudo apt install htop

六、查看制定進程的內(nèi)存

通過/proc/procid/status查看進程內(nèi)存

peng@ubuntu:~$?cat?/proc/4398/status
Name:?kworker/0:0????//進程名
Umask:?0000
State:?I?(idle)???//進程的狀態(tài)
//R?(running)",?"S?(sleeping)",?"D?(disk?sleep)",?"T?(stopped)",?"T(tracing?stop)",?"Z?(zombie)",?or?"X?(dead)"
Tgid:?4398?//線程組的ID,一個線程一定屬于一個線程組(進程組).
Ngid:?0
Pid:?4398?//進程的ID,更準(zhǔn)確的說應(yīng)該是線程的ID.
PPid:?2??//當(dāng)前進程的父進程
TracerPid:?0?//跟蹤當(dāng)前進程的進程ID,如果是0,表示沒有跟蹤
Uid:?0?0?0?0
Gid:?0?0?0?0
FDSize:?64?//當(dāng)前分配的文件描述符,該值不是上限,如果打開文件超過64個文件描述符,將以64進行遞增
Groups:?//啟動這個進程的用戶所在的組
NStgid:?4398
NSpid:?4398
NSpgid:?0
NSsid:?0
Threads:?1
SigQ:?0/7640
SigPnd:?0000000000000000
ShdPnd:?0000000000000000
SigBlk:?0000000000000000
SigIgn:?ffffffffffffffff
SigCgt:?0000000000000000
CapInh:?0000000000000000
CapPrm:?0000003fffffffff
CapEff:?0000003fffffffff
CapBnd:?0000003fffffffff
CapAmb:?0000000000000000
NoNewPrivs:?0
Seccomp:?0
Speculation_Store_Bypass:?vulnerable
Cpus_allowed:?00000000,00000000,00000000,00000001
Cpus_allowed_list:?0
Mems_allowed:?00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list:?0
voluntary_ctxt_switches:?5
nonvoluntary_ctxt_switches:?0

總結(jié):

確定內(nèi)存使用情況是Linux運維工程師必要的技能,尤其是某個應(yīng)用程序變得異常和占用系統(tǒng)內(nèi)存時。當(dāng)發(fā)生這種情況時,知道有多種工具可以幫助你進行故障排除十分方便的。

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄

公眾號『一口Linux』號主彭老師,擁有15年嵌入式開發(fā)經(jīng)驗和培訓(xùn)經(jīng)驗。曾任職ZTE,某研究所,華清遠(yuǎn)見教學(xué)總監(jiān)。擁有多篇網(wǎng)絡(luò)協(xié)議相關(guān)專利和軟件著作。精通計算機網(wǎng)絡(luò)、Linux系統(tǒng)編程、ARM、Linux驅(qū)動、龍芯、物聯(lián)網(wǎng)。原創(chuàng)內(nèi)容基本從實際項目出發(fā),保持原理+實踐風(fēng)格,適合Linux驅(qū)動新手入門和技術(shù)進階。