Linux對大部分申請內存的請求都回復"yes",以便能跑更多更大的程序。因為申請內存後,並不會馬上使用內存。這種技術叫做Overcommit。
當內存不足時,會發生OOM killer(OOM=out-of-memory)。它會選擇殺死一些進程(用戶態進程,不是內核線程),以便釋放內存。
Overcommit和下面兩個vm的配置有關系。
vm.overcommit_ratio vm.overcommit_memory
0 — 默認設置。個人理解:當應用進程嘗試申請內存時,內核會做一個檢測。內核將檢查是否有足夠的可用內存供應用進程使用;如果有足夠的可用內存,內存申請允許;否則,內存申請失敗,並把錯誤返回給應用進程。舉個例子,比如1G的機器,A進程已經使用了500M,當有另外進程嘗試malloc 500M的內存時,內核就會進行check,發現超出剩余可用內存,就會提示失敗。 1 — 對於內存的申請請求,內核不會做任何check,直到物理內存用完,觸發OOM殺用戶態進程。同樣是上面的例子,1G的機器,A進程500M,B進程嘗試malloc 500M,會成功,但是一旦kernel發現內存使用率接近1個G(內核有策略),就觸發OOM,殺掉一些用戶態的進程(有策略的殺)。 2 — 當 請求申請的內存 >= SWAP內存大小 + 物理內存 * N,則拒絕此次內存申請。解釋下這個N:N是一個百分比,根據overcommit_ratio/100來確定,比如overcommit_ratio=50,那麼N就是50%。
只有當vm.overcommit_memory = 2的時候才會生效,內存可申請內存為
SWAP內存大小 + 物理內存 * overcommit_ratio/100
$ grep -i commit /proc/meminfo CommitLimit: 517584 kB Committed_AS: 3306488 kB CommitLimit:最大能分配的內存(個人理解僅僅在vm.overcommit_memory=2時候生效),具體的值是 SWAP內存大小 + 物理內存 * overcommit_ratio / 100 Committed_AS:當前已經分配的內存大小