本章說明Linux的內存管理特征,即虛擬內存和磁盤緩存。描述系統管理員應該考慮的東西、工作和目的。
什麼是虛擬內存?
Linux支持虛擬內存, 就是使用磁盤作為RAM的擴展,使可用內存相應地有效擴大。核心把當前不用的內存塊存到硬盤,騰出內存給其他目的。當原來的內容又要使用時,再讀回內存。這對用戶全透明:運行於Linux的程序只看到大量的可用內存而不甘心哪部分在磁盤上。當然,讀寫硬盤比真的內存慢(慢千倍),所以程序運行較慢。用做虛擬內存的這部分硬盤叫 對換空間。
Linux可以使用文件系統中的普通文件或單獨的分區作為對換空間。對換分區更快,但對換文件更易於改變大小(無須對硬盤重分區)。如果知道要多少對換空間,應該用對換分區;如果不能確認,可以先用對換文件,用一段時間後再根據所需空間建立對換分區。
Linux允許同時使用多個對換分區和/或對換文件。即如果偶爾需要更多的對換空間,可以隨時建立一個額外的對換文件。
產生對換空間
對換文件是普通文件,對核心沒有什麼特別的。唯一不同是它沒有孔,用 mkswap 准備。必須在本地盤上,不能在通過NFS mount的文件系統中。
關於孔,是重要的。對換文件保留了磁盤空間,使核心能快速對換出一頁,而不必經過如文件的定位磁盤扇區的全部事情。核心只用分配給這個文件的所有扇區。由於文件中的孔意味著沒有為文件中這個位置分配磁盤扇區,這對核心使用不利。
產生沒有孔的對換文件的一個好辦法是通過如下命令:
$ dd if=/dev/zero of=/extra-swap bs=1024 count=1024
1024+0 records in
1024+0 records out
$
/extra-swap 是對換文件名,大小由count=給出. 大小最好是4的倍數,因為核心寫出的內存頁是4KB。如果不是4的倍數,最後那幾KB將不可用。
對換分區也沒什麼特別。就象產生其他分區一樣產生;唯一的不同是它作為原始分區使用,即沒有任何文件系統,最好將對換分區標記為類型82(Linux swap),雖然這對核心沒有影響,但這使分區列表更清晰。
產生對換文件或對換分區後,需要寫個標記起用它,這包括核心要用的一些管理信息。命令是 mkswap , 用法如下:
$ mkswap /extra-swap 1024
Setting up swapspace, size = 1044480 bytes
$
注意對換空間現在還沒用,它存在,但核心還沒用它提供虛擬內存。
請一定小心使用mkswap , 因為它不檢查文件或分區是否被其他東西使用。 你可能用mkswap 很容易地覆蓋了重要文件和分區! 幸好,你只需在你安裝系統時使用mkswap 。
Linux內存管理限制了每個對換空間約為127MB(由於技術原因,實際限制是127.6875MB)。 可以同時使用最多16個對換空間,總計差不多2GB。
使用對換空間
用swapon 將一個初始化的對換空間可用。此命令告訴核心對換空間可以用了,對換空間的路徑作為參數,啟動一個臨時對換文件可以用如下命令:
$ swapon /extra-swap
$
對換空間如果列入/etc/fstab ,就可自動使用。
/dev/hda8 none swap sw 0 0
/swapfile none swap sw 0 0
啟動手稿運行命令swapon -a, 它將啟動/etc/fstab 中所列的所有對換空間。因此swapon 命令只有在啟動額外的對換空間時才使用。
可以用free 監視對換空間的使用,它將給出所有使用的對換空間。
$ free
total used free shared buffers
Mem: 15152 14896 256 12404 2528
-/+ buffers: 12368 2784
Swap: 32452 6684 25768
$
前一行輸出(Mem:)顯示物理內存。 Total列不顯示核心使用的物理內存(通常大約1MB)。Used列顯示被使用的內存總額(第二行不計緩沖)。 Free列顯示全部沒使用的內存。Shared列顯示多個進程共享的內存總額。Buffers列顯示磁盤緩存的當前大小。
後一行(Swap:)對對換空間,顯示的信息類似上面。如果這行為全0,那麼沒使用對換空間。
通過top ,或使用proc文件系統的/proc/meminfo 文件可以得到相同的信息。得到某個對換空間的使用信息目前還比較困難。
可用swapoff 取消對換空間,一般不必這樣,除非是臨時對換空間。對換空間中的要用的頁被換入(swap->RAM),如果沒有足夠的物理內存,就被換出(RAM->swap,到其他對換空間)。如果沒有足夠的虛擬內存放進所有頁面,Linux將開始震蕩(thrash); 很長時間以後應該能恢復,但此時系統不可用。取消一個對換空間前,應該檢查(例如用free )是否有足夠的物理內存。
用swapon -a自動使用的所有對換空間可以用swapoff -a取消。它查看文件/etc/fstab 得知要取消什麼。任何手工起用的對換空間將依然使用著。
即使有許多空閒的物理內存,有時許多對換空間也被使用著。這種情況是由於在某個時間需要對換,但後來一個占用大量物理內存的大進程終止並釋放了內存。直到被換出的數據要被使用之前它們並不自動換入。不必顧慮這種情況,但知道為什麼會發生這種情況會更安心。
與其他操作系統共享對換空間
許多操作系統內置虛擬內存。由於他們只需在運行時使用,即,不會同時,那麼除了當前運行的,其他所有對換空間都浪費著。如果他們共享同一個對換空間將更有效。這是可能的但需要一些Hacking工作。 Tips-HOWTO包含了一些如何完成這項任務的忠告。
分配對換空間
也許有人告訴你,應該分配2倍於物理內存的對換空間,但這是個虛假的規律。下面說明如何正確:
估計你的全部內存需求。這是你可能需要的最大量,即你要同時運行的所有程序所需的內存要求的總和。你可以同時運行你可能同時運行的所有程序試試。
例如,如果你想運行X,你得分配8MB給他,gclearcase/" target="_blank" >cc要求數MB(有些文件偶爾可能需要很大量,數十MB,但一般4MB差不多),等等。核心自己使用1MB,Shell和一些小工具可能需要幾百KB(或說,總共1MB)。不必太精確,粗略估計就行,但可以較悲觀地考慮。
記得如果將有多人同時使用系統,他們將都消耗內存。如果2個人同時運行相同的程序,總內存消耗一般並非加倍,因為代碼頁和共享庫是單一的。
free 和ps 命令對估計內存需求很有用。
第一步的估計加上一些安全量。因為對程序大小的估計很可能是錯誤的,因為你可能忘了一些要運行的程序,並確定你有一些額外空間。應該有數MB。(分配太多對換空間比分配太少好,但不必過分,因為不使用的對換空間是浪費;見後文:關於增加對換空間。) Also,since it is nicer to deal with even numbers, you can round the value up to the next full megabyte.
基於以上計算,你知道了你總共需要多少內存。減去你的實際物理內存,就是對換空間。 (有些版本的UNIX中,你還需要分配物理內存的映象空間,所以第二布中計算的你所需的空間就不能減)
如果你計算的對換空間比你的實際物理內存大得多(大於好幾倍以上),那麼你也許需要更多的物理內存,否則系統性能將太低。
即使計算顯示你無須對換空間,最好還是至少有一些。Linux有些侵略性地使用對換空間,這樣保持一定的空閒物理內存。即使內存還不為什麼程序所需,Linux也會換出一些不用的內存頁,這樣在需要的時候就可以避免因對換的等待--即對換可以在硬盤空閒的時候提早完成。
對換空間可以分在幾個硬盤中,這有時可以提高性能,依賴於這些盤的相對速度和存取模式。你可以嘗試幾中方案,但要知道正確地嘗試是很困難的。不要相信某種方案比其他方案好的斷定,因為它不會總是對的。
高速緩存
與存取(真正的)內存相比,從磁盤讀是很慢的 另外,在相對短的一端時間裡,多次讀硬盤相同的部分是很常見的。例如,你可能先讀了一封電子郵件,然後回復時又將它讀入編輯器,然後復制它到一個文件夾時又用郵件程序讀它。或者,考慮命令ls 可能被系統上的很多用戶多麼頻繁地使用。只從磁盤讀一次信息,並保持在硬盤中,知道不再需要,除了第一次讀,其他都會較快。這就叫磁盤緩存disk buffering,用於此目的的內存叫buffer cache。
不幸的是,由於內存是有限且缺乏的資源,buffer cache一般不會足夠大(大到能夠裝下所有人可能用到的數據)。當cache滿時,最長時間不用的數據將被丟棄,內存釋放給最新的數據。
磁盤緩沖也用於寫操作。要寫的數據經常馬上又被讀(例如一個源代碼文件保存到文件中後又被編譯器讀出),所以將要寫的數據放在緩沖裡是個好主意。另外,只將數據放如cache而不馬上寫到磁盤,寫操作的程序執行速度更快。寫操作然後可以在後台完成,而不降低其他程序的速度。
許多操作系統有buffer caches (即使名稱不同),但並非都根據上述原理。有些是透寫write-through: 數據馬上寫到磁盤(當然也同時寫到cache) 不馬上寫的cache叫回寫write-back。回寫比透寫更有效,但也更容易出錯:如果系統崩潰,或電源突然掉電,或軟盤在cache回寫前被取出,那麼cache中改變的數據將丟失。這可能意味著文件系統is not in full working order, 可能由於未寫數據包含了系統記錄信息的重要的變化。
因此,千萬不要不經過正常的關閉過程直接關閉電源(見6章), 或沒有unmount就取出軟盤(如果是mount的),或什麼程序還在用著軟盤,或軟盤燈還在閃。 sync 命令刷新緩沖,即強制將所有未寫數據寫回磁盤,如果要確保所有數據安全回寫,可以用它。傳統的UNIX系統中,有個update 程序在後台運行,它每30秒運行一次 sync ,所以通常無須使用sync 。 Linux有一個另外的守侯程序bdflush ,它克服了sync 有時因磁盤I/O負荷太重(因為頻繁的操作)而導致有時系統突然呆住的問題。
Linux下,bdflush 由update 啟動。一般無須考慮它,但如果bdflush 偶爾因為什麼原因死了,核心會給出警告,此時應該手工啟動它(/sbin/update )。
cache並不真正緩沖文件,而是塊,就是磁盤I/O的最小單元(Linux下,一般是1kB)。這樣,所有的目錄、超級塊、其他文件系統記錄數據和無文件系統磁盤都可以被緩沖。
cache的效果決定於其大小。太小的cache幾乎無用;它只能cache很少的數據,而可能在被重用前就被清除了。大小有賴於有多少數據被讀寫,相同的數據的存取頻度。唯一的方法是實驗。
如果cache是固定大小,那麼不應該太大,否則,會由於空閒內存空間太小而使用swap(也很慢)。為了最有效地使用真實內存,Linux自動使用所有空閒內存作為buffer cache,當程序需要更多內存時,自動減少cache。
Linux下,對cache使用無須做任何工作,它完全是自動的。除了要正常關閉系統和取出軟盤,無須關心cache。