Linux - 查看內存占用: top和free的區別
一、top
能夠實時(監控)顯示系統中各個進程的資源占用狀況,類似于Windows的任務管理器。
默認進入top時,各進程是按照CPU的占用量來排序,以K為單位顯示內存大小,可通過大寫字母E來切換內存信息區域的顯示單位,如下按一下E切換到MB,再按一下E切換到GB。
注意:按shift+M使應用按內存使用率排序,定位到第一個使用內存最高的應用,并找到對應的PID。
top命令常用的選項參數:
top [選項]
例如:
top 每隔3秒顯式所有進程的資源占用情況
top -d 1 每隔1秒顯式所有進程的資源占用情況
top -c 每隔3秒顯式進程的資源占用情況,并顯示進程的命令行參數(默認只有進程名)
top -p 28820 -p 38830 每隔3秒顯示pid是28820和pid是38830的兩個進程的資源占用情況
top -d 2 -c -p 69358 每隔2秒顯示pid是69358的進程的資源使用情況,并顯式該進程啟動的命令行參數

交互命令:
1)敲top后,按鍵盤數字“1”可以監控每個邏輯CPU的狀況;
2)敲top后,輸入u,然后輸入用戶名,則可以查看相應的用戶進程;
3)敲top后,默認以K為單位顯示內存大小,可以通過大寫字母E來切換內存信息區域的顯示單位,按一下E切換到MB,再按一下E切換到GB;
4)敲top后,輸入h進入top命令的幫助文檔,了解更多關于top的用法。

1)總覽區:(含義分別如下)
第一行(top):
up:系統當前時刻,
days:系統啟動后到現在的運作時間,
users:當前登錄到系統的用戶終端數,
load average:當前系統負載的平均值,后面的三個值分別為1分鐘前、5分鐘前、15分鐘前進程的平均數;
注意:負載值一般不超過cpu核數的1-1.5倍,如果超過1.5倍,那就要重視,此時會嚴重影響系統。

根據經驗法則, 建議生產系統的 CPU 總使用率不要超過 70%。
1)、查看服務器的CPU個數
cat /proc/cpuinfo| grep “physical id”| sort| uniq| wc -l
2)、查看服務器的CPU物理核數
cat /proc/cpuinfo| grep “cpu cores”| uniq
注:查的是每顆CPU的物理核數
3)、查看服務器的CPU邏輯核數
cat /proc/cpuinfo | grep “siblings” | uniq --查看單顆CPU的邏輯核數
cat /proc/cpuinfo| grep “processor”| wc -l --查看所有CPU的邏輯核數
查看cpu個數:
cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l
lscpu //顯示有關 CPU 架構的信息

例如:cpu核數是4,負載值在4以下是屬于正常,短時間內4~6問題不大,超過6那就有大問題。

第二行(Tasks):
total:當前系統進程總數,
running:當前運行中的進程數,
sleeping:當前處于等待狀態中的進程數,
stopped:被停止的系統進程數,
zombie:僵尸進程數;

第三行(Cpu):
us:用戶空間占用CPU百分比(像shell程序、各種語言的編譯器、各種應用、web服務器和各種桌面應用都算是運行在用戶地址空間的進程,這些程序如果不是處于idle狀態,那么絕大多數的CPU時間都是運行在用戶態)
sy:內核空間占用CPU百分比(所有進程要使用的系統資源都是由Linux內核處理的,對于操作系統的設計來說,消耗在內核態的時間應該是越少越好,在實踐中有一類典型的情況會使sy變大,那就是大量的IO操作,因此在調查IO相關的問題時需要著重關注它)
ni:用戶進程空間內改變過優先級的進程占用CPU百分比(ni是nice的縮寫,可以通過nice值調整進程用戶態的優先級,這里顯示的ni表示調整過nice值的進程消耗掉的CPU時間,如果系統中沒有進程被調整過nice值,那么ni就顯示為0)
id:空閑CPU百分比,
wa:等待輸入輸出的CPU時間百分比(和CPU的處理速度相比,磁盤IO操作是非常慢的,有很多這樣的操作,比如,CPU在啟動一個磁盤讀寫操作后,需要等待磁盤讀寫操作的結果。在磁盤讀寫操作完成前,CPU只能處于空閑狀態。Linux系統在計算系統平均負載時會把CPU等待IO操作的時間也計算進去,所以在看到系統平均負載過高時,可以通過wa來判斷系統的性能瓶頸是不是過多的IO操作造成的)
hi:硬件CPU中斷占用百分比(硬中斷是硬盤、網卡等硬件設備發送給CPU的中斷消息,當CPU收到中斷消息后需要進行適當的處理,消耗CPU時間)
si:軟中斷占用百分比(軟中斷是由程序發出的中斷,最終也會執行相應的處理程序,消耗CPU時間)
st:虛擬機占用百分比(steal time,虛擬機進程在物理CPU上等待其CPU時間的時間百分比)

第四行(KiB Mem,實體內存):
total:物理內存總量,
used:使用的物理內存總量,
free:空閑內存總量,
buffers:用作內核緩存的內存量;

第五行(KiB Swap,虛擬內存):
total:交換區總量,
userd:使用的交換區總量,
free:空閑交換區總量,
cached:緩沖的交換區總量;

注意:
第四、第五行分別是內存信息和swap信息,所有程序的運行都是在內存中進行的,所以內存的性能對與服務器來說非常重要。不過當內存信息的free變少的時候,其實并不需要太緊張。真正需要看的是Swap中的used信息。Swap分區是由硬盤提供的交換區,當物理內存不夠用的時候,操作系統才會把暫時不用的數據放到Swap中。所以當這個數值變高的時候,說明內存是真的不夠用了。
2)進程列表欄:(含義分別如下)
PID:進程的ID,
USER:進程所有者,
PR:進程的優先級別,越小越優先被執行,
NI:nice值,負值表示高優先級,正值表示低優先級,
VIRT:進程占用的虛擬內存,單位kb,
RES:進程占用的物理內存,單位kb,
SHR:進程使用的共享內存,單位kb,
S:進程的狀態,S表示休眠,R表示正在運行,Z表示僵死狀態,N表示該進程優先值為負數,
%CPU:進程占用CPU的使用率,
%MEM:進程使用的物理內存和總內存的百分比,
TIME+:該進程啟動后占用的總的CPU時間,
COMMAAND:進程啟動命令名稱

二、free
顯示內存的使用情況,包括實體內存,虛擬(交換文件)內存,共享內存區段,以及系統核心使用的緩沖區等。

例如:
free -s 5 //,每隔5s重新查詢一次
1)Mem是實體內存,物理內存空間使用情況
2)SWAP是交換分區(虛擬內存),物理內存不夠用時,臨時存放數據
3)free 是真正從尚未被使用的物理內存數量
4)available 是從應用程序角度看到的可用內存數量【含緩存,程序“認為”還可以被使用的內存】
5)buffer 和 cache 都屬于已經被使用的內存。當應用程序需要內存時,如果沒有足夠的 free 內存可以用,內核就會從 buffer 和 cache 中回收內存來滿足應用程序的請求
6)Linux為了提高讀寫性能,會拿出一部分內存來臨時存儲數據(也就是系統內存緩存),當剩余的內存(free)不夠的時候,就會釋放一部分緩存(buff/cache)來滿足程序的使用需求,即:available = free + buff/chche(部分可以被釋放的緩存)


total 去掉為硬件和操作系統保留的內存后剩余的內存總量
used 當前已使用的內存總量
free 空閑或可以使用的內存總量
shared 共享內存大小,主要用于進程間通信
buff/cache 主要用于塊設備數據緩沖,例如記錄文件系統的metadata(目錄、權限等等信息)
available 可以使用的內存總量
// 內存總數與已使用內存和空閑內存數的關系
total=used+free
虛擬內存(Swap):
首先需要強調的是虛擬內存不同于物理內存,雖然兩者都包含“內存”字眼,但它們屬于兩個不同層面的概念。進程占用虛擬內存空間大并非意味著程序的物理內存也一定占用很大。虛擬內存是操作系統內核為了對進程地址空間進行管理而精心設計的一個邏輯意義上的內存空間概念。我們程序中的指針其實都是這個虛擬內存空間中的地址。比如我們在寫完一段C++程序之后都需要采用g++進行編譯,這時候編譯器采用的地址其實就是虛擬內存空間的地址。因為這時候程序還沒有運行,何談物理內存空間地址?凡是程序運行過程中可能需要用到的指令或者數據都必須在虛擬內存空間中。既然說虛擬內存是一個邏輯意義上(假象)的內存空間,為了能夠讓程序在物理機器上運行,那必須有一套機制可以讓這些假象的虛擬內存空間映射到物理內存空間(實實在在的RAM內存條上的空間)。這其實就是操作系統中頁映射表(page table)所做的事情了。內核會為系統中每一個進程維護一份相互獨立的頁映射表,頁映射表的基本原理是將程序運行過程中需要訪問的一段虛擬內存空間通過頁映射表映射到一段物理內存空間上,這樣CPU訪問對應虛擬內存地址的時候就可以通過這種查找頁映射表的機制訪問物理內存上的某個對應的地址。“頁(page)”是虛擬內存空間向物理內存空間映射的基本單元。
虛擬內存的引入,每個進程都擁有自己獨立的虛擬地址空間,進程與進程之間的虛擬內存地址空間是相互隔離,互不干擾,而且每個進程都認為自己獨占所有內存空間。如此,就可以將多進程之間協同的相關復雜細節統統交給內核中的內存管理模塊來處理,極大地解放了程序員的負擔。這一切都是因為虛擬內存能夠提供內存地址空間的隔離,極大地擴展了可用空間。當CPU訪問進程的虛擬地址時,經過地址翻譯硬件將虛擬地址轉換成不同的物理地址,這樣不同的進程運行時,既是操作的是同一虛擬地址,背后寫入的也是不同的物理地址。
對于一臺真實的計算機來說,它的虛擬內存空間有多大呢?計算機虛擬內存空間的大小是由程序計數器的尋址能力來決定的。
例如:在程序計數器的位數為32的處理器中,它的虛擬內存空間就為4GB。
如何判斷內存是否夠用?(內存使用情況分析技巧)
當系統的物理內存不夠用時,就會把一部分不常用的數據臨時放到交換分區(Swap),等到程序要使用這些數據時,再把它們從交換分區加載到物理內存中。這就意味著,系統總是在內存不夠用的情況下,才會使用交換分區。如果交換分區沒被使用或者使用的很少,內存夠用(使用情況良好);反之,就說明內存不夠用了,可能會影響到系統的使用。
交換分區可以在一定程度上解決內存不足的問題,但它會讀取磁盤的數據,所以讀寫速度不快,因此,只有在內存不夠用時,才會選擇把數據放到交換分區。
例如:
使用 free -m //查看系統還剩多少兆內存可以使用【重點是看free那一列】

此時服務器的內存還剩809MB(總共257415MB,已使用66759MB,緩存用了189847MB),屬于不正常的情況:
緩存占了太多的內存,服務器上的應用可能就會出現功能無法正常使用的問題,如果需要緊急恢復使用,可以重啟服務,釋放緩存;如果不緊急,就找專業人員分析一下具體的原因。
問題定位
cached 占用過高問題
buffer,cached的作用:cached主要負責緩存文件使用, 日志文件過大造成cached區內存增大把內存占用完
Free中的buffer和cache:(它們都是占用內存)
buffer : 作為buffer cache的內存,是塊設備(磁盤)的緩沖區,包括讀、寫磁盤
cache: 作為page cache的內存, 文件系統的cache,包括讀、寫文件
如果 cache 的值很大,說明cache住的文件數很多。
linux服務器會自動釋放內存,保障系統運行,但只會釋放夠用的內存,而不會去釋放更多的內存。
解決方法:
手動(臨時)釋放cached方法:
釋放前最好sync一下,防止丟數據。sync 在啟動機器或關機之前一定要運行sync命令。
記住:在任何情況下,慎重地執行sync命令決不會有任何壞處,sync命令強制把磁盤緩沖的所有數據寫入磁盤。
要達到釋放緩存的目的,需要了解下關鍵的配置文件/proc/sys/vm/drop_caches,默認為0

echo 1 > /proc/sys/vm/drop_caches // 清理pagecache(頁面緩存)
echo 2 > /proc/sys/vm/drop_caches // 清理dentries(目錄緩存)和inodes
echo 3 > /proc/sys/vm/drop_caches // 清理pagecache、dentries和inodes
sync // 將存于 buffer 中的資料強制寫入硬盤中【用于數據同步,在關閉Linux系統時使用】
#常用方法
sync //使用sync命令來清理文件系統緩存,還會清理僵尸(zombie)對象和它們占用的內存
echo 1 > /proc/sys/vm/drop_caches
#清除后要還原系統默認配置:(系統默認值是0,釋放之后需要再改回0值):
echo 0 > /proc/sys/vm/drop_caches
#查看設置
sysctl -a | grep drop_caches
這時,查看 free 可以看到 cached 降低了很多。
例如:

查看內存占用高的前20:
ps aux | head -1;ps aux |grep -v PID |sort -rn -k +4 | head -20
補充: echo 字符串 > 文件 就是把字符串內容從定向到文件中
原理(free數據來源)
free命令實際上是在查詢 /proc/meminfo,查看這個文件,會發現里面有很多字段,單位是KB,所以free不加參數時,默認單位就是KB。
cat /proc/meminfo

浙公網安備 33010602011771號