天天3分鐘操做系統修煉祕籍(12):OOM和swap分區

點我查看祕籍連載算法

OOM和swap分區

進程的虛擬內存空間是映射到整個物理內存空間的,因此在進程自身看來它擁有了整個物理內存,它也能使用整個物理內存,只需在使用的時候請求操做系統幫忙分配更多空間便可。服務器

可是,操做系統上並不是只運行了一個進程,若是一個進程無休止的申請物理內存空間,最終會致使物理內存耗盡或即將耗盡,使得操做系統沒法建立新進程,由於建立新進程須要爲它分配虛擬內存。ide

因此,操做系統必須得監視物理內存的使用狀況,在出現物理內存耗盡或即將耗盡的時候,若是進程繼續請求分配內存,將報錯out-of-memory(OOM)表示內存不足,而且在出現OOM的時候,操做系統將觸發OOM Killer程序從進程列表中篩選出一個內存密集型進程殺掉,從而釋放大片內存。但顯然,這是不怎麼友好的方式,很多服務器都專門或主要運行一個服務,若是這個服務進程正好申請了大量內存,它極可能會被OOM Killer殺掉,從而致使服務中止。操作系統

其實,早期內存通常都比較小,很容易就出現內存不足的問題,因此很早就提出了一個交換分區(swap partition)的概念。線程

swap分區是將磁盤看成內存使用,使得虛擬地址空間的範圍大小能夠超出物理內存的實際大小,在物理內存空間不足時,能夠將物理內存中的一些不重要數據拷貝到磁盤的swap分區中,從而讓出內存空間,而且在須要那些已被拷出數據時再從swap分區中拷回到內存,從而再也不那麼容易發生OOM錯誤。翻譯

可是swap分區畢竟是在磁盤上,而且要在內存和磁盤之間傳遞數據,因此要訪問swap分區上的數據時速度會很是慢。在目前大內存都已足夠廉價的狀況下,已經沒有多少必要使用swap分區。blog

雖然,如今swap分區對進程來講不多派上用場,但涉及到的一些技術和概念有必要簡單介紹下。進程

使用swap分區第二個要解決的問題是,如何讓虛擬地址空間的頁映射到磁盤swap分區的頁上。也就是,如何將虛擬頁翻譯成swap頁,而且在訪問時怎麼知道這不是內存的物理頁。內存

由於在物理內存的基礎上引入了swap分區,因此每一個虛擬頁中都有一個存在位來表示該頁是否存在於內存中,若是該位的值爲1,表示駐留在內存中,若是爲0則表示在swap分區而非內存。其中,全部駐留在內存中的頁也稱爲駐留集(Resident Set)。資源

當訪問一個虛擬頁的時候,若是發現不在內存中,這時候會產生缺頁異常(page fault),也稱爲頁未命中(page miss),因而陷入操做系統,啓動頁錯誤處理程序,從swap分區中找到對應的頁(顯然,這裏須要將虛擬內存頁翻譯成swap分區頁的地址)並拷貝到內存中。從swap分區拷入頁的過程稱爲換入頁(page in)。

這裏產生了一個新問題,既然已經使用了swap分區,說明此時物理內存已經處於緊張狀態,從swap中page in的頁如何放進內存中?其實,這裏也須要先進行page out,將該進程的一頁或多頁page out以便騰出內存。那麼哪些運氣很差的頁會被page out呢?這裏又出現了策略算法,稱爲頁替換策略算法,用來決定哪些頁應該被page out,好比使用FIFO算法換出那些先進入的頁,使用隨機算法隨機選擇換出的頁,使用LRU算法選擇最近最不經常使用的頁等等。

其實,除了page out換出頁騰出少許內存空間外,操做系統還設置了兩個關於空閒頁數量(顯然,這是物理頁)的水位線:高水位線(High Watermark,HW)和低水位線(Low Watermark,LW)。當操做系統發現空閒頁的數量少於低水位線的值時,就會自動啓動一個稱爲swap daemon(也稱爲page daemon)的後臺線程kswapd,該線程會掃描全部進程並從中選出一些候選進程,而後將這些進程的全部頁都拷貝到swap分區,直到空閒物理內存頁的數量達到高水位線的值。

提示:高水位線和低水位線

在計算機領域中,常會使用高水位線和低水位線來監視進程的一些可用性資源。當這類可用性資源的數量高於或臨近高水位線的值時,代表資源充足。當可用性資源的數量已經低於低水位線,說明資源緊張,應當採起一些措施恢復一些資源。

其中,換出進程全部頁到swap分區的過程稱爲swap out,而從swap分區拷入進程全部頁的過程(好比再次調度到該進程)稱爲swap in。將這兩個概念與page out和page in區分如下:

  • page in和page out是拷入或拷出進程的一頁或某些頁
  • swap in和swap out是拷入或拷出進程的全部頁

關於swap分區,能不用的話最好仍是不用,由於當真正用到swap分區的時候,內存已經進入了緊張狀態,以後的絕大多數進程基本上都會涉及到swap分區,不斷地出現page fault而進行換頁,這會致使進程抖動(thrashing),使得總體效率低下,並且這個狀態是持續的,直到釋放足夠的內存空間。這時候還不如採起其它辦法釋放內存空間,例如殺掉某些無關進程、重啓內存密集型服務、重啓機器等。

相關文章
相關標籤/搜索