Linux 是怎樣使用內存的?

意外發現 swap 分區沒有使用,, 著手去改配置,,

發現 free 命令出來的參數好懵懂啊, 求指點


我還以為這個問題很簡單,本來覺得沒有必要回答的,但看看現有的三個答案,似乎都沒有回答問題,那就我來回答一下吧。

題主的問題不是如何配置swap,而是配置了swap後,free這個命令看不懂。作為一個Linux用戶,你首先要理解Linux的內存管理中的基本概念。

Linux的內存分兩部分,一部分是內核用的,就是驅動等模塊直接分配的內存,這以slab內存為主,背後是真實的物理內存。一部分是進程用的內存,這是Linux使用內存的大頭。

第二個你要理解的問題是,Linux對進程內存的管理策略稱為Lazy策略。總的來說,凡是用不到的東西就不實際做動作,能拖多久就拖多久。你在進程里分配一片內存,只要你不往裡寫,Linux就不真的分配內存。你讀文件也一樣,只要你不真的讀到那裡,就不真的把文件讀到內存裡面。執行一個程序也一樣的,一個老大老大的程序,只要執行不到相應的位置,這個位置的代碼數據什麼的就老老實實待在磁碟上,不會進入內存中。

所以,對Linux來說,進程的內存,有真有假,有些是真的在物理內存中的,有些只是說好要,但不一定真會有的。這樣打個時間差,Linux就可以運行更多的程序了。

所以,進程分配的每片內存背後,都會有一個back log文件,你打開一個文件f,讀裡面的內容,這些內容就會寫入內存,這個內存背後的back log文件就是這個文件f。而所謂swap,就是所有其他內存(例如進程中用malloc分配的內存)的back log文件。你一定要從這個角度理解swap,後面的解釋就好理解了。

好了,你應該注意到了,如果你的內存背後有back log文件,這片內存只要不是正在被訪問,它就是可以被放棄的。因為大不了到你要用的時候,重新從磁碟中把數據讀回來而已。

現在你就可以理解free命令的輸出了,第一行的所謂free和used,就是實際的物理內存的用量。而+-buffer/cache那一行,是把buffer和cache(可以隨時被放棄的)當作空閑內存以後的free和used。你基本上可以認為第二行才表示系統中有多少內存。swap那一行,是說有多少swap被用作back log(同時被寫入)了,那個其實關係不大。

然後我們討論一下什麼是buffer和cache,其實這兩個是一個東西,都是磁碟數據讀入到內存去的部分。但Buffer是Metadata,就是記錄什麼文件名啦,創建時間啦那些數據。Cache則是文件內容。把這兩個東西分開,是因為Cache總是一頁一頁分配的,Buffer通常不大,是幾個文件用一個頁來保存的。所以通常buffer更難釋放。但free這個命令其實不是很關心這種細節啦,你要看更深入的信息,就要看/proc/meminfo和/proc/slabinfo了。如果你真的需要那些信息估計要不需要我在這裡給你解釋了。

最後我們談談怎麼設置swap。這個其實沒有固定的方法。傳統是讓你設物理內存的兩到三倍。但這個是沒有準數的,兩到三倍的邏輯是保證最壞的情況下,系統
還勉強可以運行,這樣你有維護的機會。據我所知,BAT普遍是不用swap,這可以保證性能,但降低單機可靠性。我個人通常是設很大的SWAP的,因為
tmpfs背後就是SWAP,我經常用這種文件系統做驗證,這樣比較方便,題主不用太糾結這個問題,有問題解決問題就好了。


對於伺服器,現在的推薦是不使用 swap。

不使用 swap 導致程序退出與使用 swap 導致性能退化相比,前者更易監控,更易處理,而且很少有連鎖反應。


更新修改:

大致如下:

linux在內存使用上分了四個部分:

  1. 內核代碼及內核數據,bss,pci匯流排/video等設備在內存中映射,以及內核保留內存。free 命令以及/proc/meminfo中的內存使用不包含這一部分。 這部分可以cat /var/log/dmesg* |grep -i memory 看到。

  2. 內存管理模塊(頁表,slab內存分配器)佔用一部分, 這一部分的內存。見/proc/meminfo中的slab 以及pagetable 。free 命令輸出的used列包含slab和pagetable使用的。

  3. 應用進程佔用(應用進程本身的代碼,以及常量、堆棧, 都在這一部分, 它們(指代碼/堆棧等)被放在連續的邏輯內存頁面上,但這些頁面在物理上可以是不連續的。 關於邏輯頁面和物理頁面的映射,由此進程自身的管理模塊(PCB)的頁表來管理 )。 單個進程使用的物理頁面統計可以在/proc/pid/statm 中第二列看到(第一列是虛擬內存的佔用,虛擬內存定義可自行百度),把pid換成你想查的進程,但是第二列也含有動態鏈接庫所佔用的內存。當遍歷所有進程來統計進程實際使用的內存時,(這裡只是粗略統計,因為rss是包括共享內存的,比如動態鏈接庫)有統計重複: 見下面遍歷統計內存使用腳本:

#/bin/bash

for PROC in `ls /proc/|grep "^[0-9]"`

do

if [ -f /proc/$PROC/statm ]; then

TEP=`cat /proc/$PROC/statm | awk "{print ($2)}"`

RSS=`expr $RSS + $TEP`

fi

done

RSS=`expr $RSS * 4`

echo $RSS"KB"

關於cache和buffer部分,之前的解釋有錯誤更正如下:

4. cache ,文件緩存,程序讀/寫取過的文件或經常讀取文件(2.6以後的內核,共享的動態庫文件 也在cache里),會在這一部分,再次讀相同的文件時,可以先在cache部分讀取, 以節省讀硬碟的時間。讀硬碟的速度實在太慢。

5. buffer: 緩衝,理解上相當於cache的目錄。見下面英文:

free 看到的是:

  • used: 指上面提到的 2+3+4+5

  • cache: 指上面提到4

  • buffer: 指上面提到5

swap:

理論上說 4個部分中, 當系統進程多起來(2的使用多起來),內存需求增加時,系統會自己減少4和5部分(主要是4)的內存佔用,以提供給應用程序使用。 但當內存被耗盡時, 或剩餘內存不能滿足新產生的進程對內存的需求時,swap 就被使用了。 系統進程管理模塊會從進程鏈表中找一些較少運行或運行級別低(其實都差不多)的進程,並把它們的頁面從內存中移出到 硬碟的swap區,以騰出內存空間給新的高級別的進程用。 (BTW:當你發現你的swap使用較高時 或交換頻繁時(vmstatus第7第8列為非0),多半是需要擴 內存了)


1. 確保你的交換分區 &>= 物理內存 * 2

2. 當使用需要大內存的軟體時(PyCharm等),交換分區是不死機的關鍵。

感覺速度變慢了,檢測交換分區使用量。如果使用了30%,趕緊用「kill -9 進程id」殺掉。不然真死機了,就麻煩了。


推薦閱讀:

如何看待全球PC市場Win10佔有率下降而Win7佔有率上升這一情況?
64位操作系統,64位CPU,加SSD硬碟,是不是就可以省去內存,讓CPU直接讀取硬碟里的數據?
樹莓派可以安裝的Linux發行版有哪些?
相對於 Win 8.1,Win 10 有哪些實用的新功能?
請問我下64位office 2013的時候出現提示說我電腦裡面有32位的,可是我已經逐個刪除了,為什麼還是有?

TAG:操作系統 | Linux | Swap分區 |