一、Linux內核OOM killer機制
Linux 內核有個機制叫OOM killer(Out Of Memory killer),該機制會監控那些佔用內存過大,尤其是瞬間佔用內存很快的進程,然後防止內存耗盡而自動把該進程殺掉。內核檢測到系統內存不足、挑選並殺掉某個進程的過程可以參考內核源代碼linux/mm/oom_kill.c,當系統內存不足的時候,out_of_memory()被觸發,然後調用select_bad_process()選擇一個”bad”進程殺掉。如何判斷和選擇一個”bad進程呢?linux選擇”bad”進程是通過調用oom_badness(),挑選的算法和想法都很簡單很樸實:最bad的那個進程就是那個最佔用內存的進程。
被幹掉進程信息
如需輸出確認了被kill的進程爲17982
[511250.459581] Out of memory: Kill process 17982 (java) score 77 or sacrifice child
[511250.459642] Killed process 17982 (java) total-vm:19803312kB, anon-rss:2540308kB, file-rss:0kB, shmem-rss:0kB
如下爲17982進程佔用的內存頁數量635077,換算爲內存佔用量是635077*4096=2GB
[511250.459172] [ pid ] uid tgid total_vm rss nr_ptes swapents oom_score_adj name
[511250.459549] [17982] 996 17982 4950828 635077 1629 0
每列的含義爲:
-
pid進程ID。
-
uid用戶ID。
-
tgid線程組ID。
-
total_vm虛擬內存使用(單位爲4 kB內存頁)
-
rss居民 memory 使用(單位4 kB內存頁)
-
nr_ptes頁表項
-
swapents交換條目
-
oom_score_adj通常爲0;較低的數字表示當調用OOM殺手時,進程將不太可能死亡。
二、解決方法
1、調整JVM 最大內存,小於系統最大物理內存。
2、開啓swap內存交換,參考:https://www.cnblogs.com/cheyunhua/p/8653168.html
3、關閉oomkiller。
當然,如果需要的話可以完全關閉 OOM killer(不推薦用在生產環境):
# sysctl -w vm.overcommit_memory=2 # echo "vm.overcommit_memory=2" >>
參考文獻: