日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

前言

前面我們我們已經了解了linux是如何進行內存分配的、虛擬內存和物理內存的關系、虛擬內存如何管理,今天我們來學習一下系統內存滿了,會發生什么?以及會帶來什么問題?大致分成這四個內容來進行學習。

  • 內存分配的過程
  • 哪些內存可以被回收
  • 內存回收帶來的問題
  • 如何保障一個進程不被kill

 

內存分配的過程

前面我們已經學習過應用程序通過 malloc 函數申請內存的,需要注意的是,malloc() 分配的是虛擬內存

如果分配后的虛擬內存沒有被訪問的話,虛擬內存是不會映射到物理內存的,這樣就不會占用物理內存了。

只有在訪問已分配的虛擬地址空間的時候,操作系統通過查找頁表,發現虛擬內存對應的頁沒有在物理內存中,就會觸發缺頁中斷,然后操作系統會建立虛擬內存和物理內存之間的映射關系。

缺頁中斷就是要訪問的頁不在主存,需要操作系統將其調入主存后再進行訪問。在這個時候,被內存映射的文件實際上成了一個分頁交換文件。

如果沒有空閑的物理內存,那么內核就會開始進行回收內存的工作,回收的方式主要是兩種:直接內存回收和后臺內存回收。

  • 后臺內存回收(kswapd):在物理內存緊張的時候,會喚醒 kswapd 內核線程來回收內存,這個回收內存的過程異步的,不會阻塞進程的執行。
  • 直接內存回收(direct reclAIm):如果后臺異步回收跟不上進程內存申請的速度,就會開始直接回收,這個回收內存的過程是同步的,會阻塞進程的執行。

如果直接內存回收后,空閑的物理內存仍然無法滿足此次物理內存的申請,那么內核就會放最后的大招了 ——觸發 OOM 機制

OOM Killer 機制會根據算法選擇一個占用物理內存較高的進程,然后將其殺死,以便釋放內存資源,如果物理內存依然不足,OOM Killer 會繼續殺死占用物理內存較高的進程,直到釋放足夠的內存位置。

物理內存申請過程如下圖:

 

哪些內存可以被回收

系統內存緊張的時候,就會進行回收內存的工作,那具體哪些內存是可以被回收的呢?

主要有兩類內存可以被回收,而且它們的回收方式也不同。

  • 文件頁(File-backed Page):內核緩存的磁盤數據(Buffer)和內核緩存的文件數據(Cache)都叫作文件頁。大部分文件頁,都可以直接釋放內存,以后有需要時,再從磁盤重新讀取就可以了。而那些被應用程序修改過,并且暫時還沒寫入磁盤的數據(也就是臟頁),就得先寫入磁盤,然后才能進行內存釋放。所以,回收干凈頁的方式是直接釋放內存,回收臟頁的方式是先寫回磁盤后再釋放內存
  • 匿名頁(Anonymous Page):這部分內存沒有實際載體,不像文件緩存有硬盤文件這樣一個載體,比如堆、棧數據等。這部分內存很可能還要再次被訪問,所以不能直接釋放內存,它們回收的方式是通過 Linux 的 Swap 機制,Swap 會把不常訪問的內存先寫到磁盤中,然后釋放這些內存,給其他更需要的進程使用。再次訪問這些內存時,重新從磁盤讀入內存。

Swap分區在系統的物理內存不夠用的時候,把硬盤內存中的一部分空間釋放出來,以供當前運行的程序使用。那些被釋放的空間可能來自一些很長時間沒有什么操作的程序,這些被釋放的空間被臨時保存到Swap分區中,等到那些程序要運行時,再從Swap分區中恢復保存的數據到內存中

文件頁和匿名頁的回收都是基于 LRU 算法,也就是優先回收不常訪問的內存。LRU 回收算法,實際上維護著 active 和 inactive 兩個雙向鏈表,其中:

  • active_list 活躍內存頁鏈表,這里存放的是最近被訪問過(活躍)的內存頁;
  • inactive_list 不活躍內存頁鏈表,這里存放的是很少被訪問(非活躍)的內存頁;

越接近鏈表尾部,就表示內存頁越不常訪問。在回收內存時,系統就可以根據活躍程度,優先回收不活躍的內存。

內存回收帶來的問題

回收內存方式的不同。回收的內存類型的不同會帶來不同的影響,下面我們就來學習一下不同的是否,不同的類型會帶來怎樣的影響。
回收內存方式:后臺回收:直接回收

  • 一種是后臺內存回收,也就是喚醒 kswapd 內核線程,這種方式是異步回收的,不會阻塞進程。
  • 一種是直接內存回收,這種方式是同步回收的,會阻塞進程,這樣就會造成很長時間的延遲,以及系統的 CPU 利用率會升高,最終引起系統負荷飆高

可被回收的內存類型:文件頁和匿名頁

  • 文件頁的回收:對于干凈頁是直接釋放內存,這個操作不會影響性能,而對于臟頁會先寫回到磁盤再釋放內存,這個操作會發生磁盤 I/O 的,這個操作是會影響系統性能的。
  • 匿名頁的回收:如果開啟了 Swap 機制,那么 Swap 機制會將不常訪問的匿名頁換出到磁盤中,下次訪問時,再從磁盤換入到內存中,這個操作是會影響系統性能的。

可以看到,回收內存的操作基本都會發生磁盤 I/O 的,如果回收內存的操作很頻繁,意味著磁盤 I/O 次數會很多,整個系統給人的感覺就是很卡。

如何降低內存回收的影響

  • 從文件頁和匿名頁的回收操作來看,文件頁的回收操作對系統的影響相比匿名頁的回收操作會少一點,因為文件頁對于干凈頁回收是不會發生磁盤 I/O 的,匿名頁的 Swap 換入換出這兩個操作都會發生磁盤 I/O。
  • 盡早觸發 kswapd 內核線程異步回收內存 來避免應用程序進行直接內存回收。

如何保護一個進程不被 OOM 殺掉呢?

在系統空閑內存不足的情況,進程申請了一個很大的內存,如果直接內存回收都無法回收出足夠大的空閑內存,那么就會觸發 OOM 機制,內核就會根據算法選擇一個進程殺掉。

Linux 到底是根據什么標準來選擇被殺的進程呢?這就要提到一個在 Linux 內核里有一個 oom_badness() 函數,它會把系統中可以被殺掉的進程掃描一遍,并對每個進程打分,得分最高的進程就會被首先殺掉。

進程得分的結果受下面這兩個方面影響:

  • 第一,進程已經使用的物理內存頁面數。
  • 第二,每個進程的 OOM 校準值 oom_score_adj,我們可以在設置 -1000 到 1000 之間的任意一個數值,調整進程被 OOM Kill 的幾率。

函數 oom_badness() 里的最終計算方法是這樣的:

// points 代表打分的結果
// process_pages 代表進程已經使用的物理內存頁面數
// oom_score_adj 代表 OOM 校準值
// totalpages 代表系統總的可用頁面數
points = process_pages + oom_score_adj * totalpages / 1000

計算出來的值越大,那么這個進程被 OOM Kill 的幾率也就越大

每個進程的 oom_score_adj 默認值都為 0,所以最終得分跟進程自身消耗的內存有關,消耗的內存越大越容易被殺掉。我們可以通過調整 oom_score_adj 的數值,來改成進程的得分結果:

  • 如果你不想某個進程被首先殺掉,那你可以調整該進程的 oom_score_adj,從而改變這個進程的得分結果,降低該進程被 OOM 殺死的概率。
  • 如果你想某個進程無論如何都不能被殺掉,那你可以將 oom_score_adj 配置為 -1000。

我們最好將一些很重要的系統服務的 oom_score_adj 配置為 -1000,比如 sshd,因為這些系統服務一旦被殺掉,我們就很難再登陸進系統了。

不建議將我們自己的業務程序的 oom_score_adj 設置為 -1000,因為業務程序一旦發生了內存泄漏,而它又不能被殺掉,這就會導致隨著它的內存開銷變大,OOM killer 不停地被喚醒,從而把其他進程一個個給殺掉。

分享到:
標簽:內存 系統
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定