一、什么時候回收內存?
1、直接內存回收
有新的大塊內存分配請求,但是剩余內存不足。這個時候系統就需要回收一部分內存,進而盡可能地滿足新內存請求。
2、定期掃描回收(kswapd)
操作系統內核線程kswapd定期進行回收內存,並通過設定三個內存閾值來衡量內存的使用情況,分別是
- 頁最小閾值(pages_min)
- 頁低閾值(pages_low)
- 頁高閾值(pages_high)
kswapd定期掃描內存的使用情況,並根據剩余內存落在這三個閾值的空間位置,進行內存的回收操作。
1)free < pages_min:說明進程可用內存都耗盡了,觸發直接內存回收,此時只有內核才可以分配內存
2)pages_min<free<pages_low:說明內存壓力比較大,剩余內存不多了。這時 kswapd會執行內存回收,直到剩余內存大於高閾值為止。
3)pages_low<free<pages_high:說明內存有一定壓力,但還可以滿足新內存請求。
4)free>pages_high:說明剩余內存比較多,沒有內存壓力。
二、回收的方式
1、對於緩存和緩沖區的內存回收
1)對文件頁的回收,直接回收緩存
2)對臟頁的回收,寫回磁盤后再回收。
2、基於 Swap 機制,回收不常訪問的匿名頁(應用程序動態分配的堆內存),通過 Swap 機制,把它們寫入磁盤后再釋放內存。
3、oom機制進行回收
三、相關參數調整
1、內核參數vm.swappiness,決定回收緩存或swap機制回收內存的傾向
取值范圍是 0-100,
數值越大,越積極使用 Swap,也就是更傾向於回收匿名頁;
數值越小,越消極使用 Swap,也就是更傾向於回收文件頁。
0不代表不使用swap,當剩余內存 + 文件頁小於頁高閾值時,還是會發生 Swap。
2、內核參數vm.min_free_kbytes,調整內存水位
pages_min = min_free_kbytes換算為page單位,
pages_low = pages_min*5/4
pages_high = pages_min*3/2
3、oom機制
1)vm.panic_on_oom:
- 0:當內存耗盡時,內核會觸發OOM killer殺掉最耗內存的進程。
- 1:表示關閉此功能,內核直接panic
2)vm.oom_kill_allocating_task
- 0:內核檢查每個進程的分數,分數最高的進程將被kill掉
- 1:內核將kill掉當前申請內存的進程