如何解決Linux系統(tǒng)"Out of memory"錯(cuò)誤問題

linux系統(tǒng)出現(xiàn)“out of memory”錯(cuò)誤的根本解決方法包括:1.查明原因,使用top命令查看內(nèi)存占用高的進(jìn)程,或用pmap -x 分析具體內(nèi)存映射;2.增加swap空間作為應(yīng)急措施,通過創(chuàng)建swap文件并啟用;3.優(yōu)化程序代碼,減少內(nèi)存泄漏、使用高效數(shù)據(jù)結(jié)構(gòu)算法;4.使用ulimit限制進(jìn)程內(nèi)存;5.升級(jí)硬件增加物理內(nèi)存。此外,可通過free -m、vmstat、sar或grafana+prometheus監(jiān)控內(nèi)存使用情況。避免被oom killer殺死可調(diào)整oom_score_adj參數(shù)或使用cgroups限制資源。分析oom日志可通過查看/var/log/syslog或kern.log定位問題根源。

如何解決Linux系統(tǒng)"Out of memory"錯(cuò)誤問題

先說個(gè)實(shí)在的,OOM killer是linux內(nèi)核的最后一道防線。它會(huì)選擇性地殺死一些進(jìn)程,釋放內(nèi)存,保證系統(tǒng)核心功能還能運(yùn)行。但這肯定不是我們想要的,程序無故被殺,數(shù)據(jù)丟失是小,系統(tǒng)崩潰是大。所以,得從根本上解決問題。

解決方案

  1. 查明原因:誰在瘋狂吃內(nèi)存?

    最直接的辦法,用top命令。看看哪個(gè)進(jìn)程的%MEM占用率高得離譜。如果是你寫的程序,那趕緊回去debug吧。如果是一些系統(tǒng)服務(wù),那就要具體問題具體分析了。

    再高級(jí)一點(diǎn),可以用pmap -x 查看進(jìn)程的內(nèi)存映射情況,看看哪些內(nèi)存區(qū)域占用最多。pid是進(jìn)程ID,top命令里能找到。

  2. 增加Swap空間:應(yīng)急措施

    Swap空間相當(dāng)于硬盤上的虛擬內(nèi)存。當(dāng)物理內(nèi)存不夠用時(shí),系統(tǒng)會(huì)把一部分不常用的內(nèi)存數(shù)據(jù)放到Swap空間里。這能緩解燃眉之急,但速度肯定比物理內(nèi)存慢很多,所以只能算是應(yīng)急措施。

    怎么增加Swap空間?簡單說幾步:

    • 創(chuàng)建一個(gè)文件作為Swap空間:sudo fallocate -l 2G /swapfile (這里創(chuàng)建了一個(gè)2GB的Swap文件)
    • 設(shè)置正確的權(quán)限:sudo chmod 600 /swapfile
    • 格式化為Swap文件系統(tǒng):sudo mkswap /swapfile
    • 啟用Swap空間:sudo swapon /swapfile
    • 添加到/etc/fstab,讓系統(tǒng)啟動(dòng)時(shí)自動(dòng)啟用:echo ‘/swapfile swap swap defaults 0 0’ | sudo tee -a /etc/fstab

    別忘了,Swap空間不是萬能的。頻繁的Swap操作(thrashing)會(huì)導(dǎo)致系統(tǒng)性能急劇下降。

  3. 優(yōu)化程序:釜底抽薪

    如果內(nèi)存占用是程序造成的,那就要優(yōu)化代碼了。常見的優(yōu)化手段包括:

    • 減少內(nèi)存泄漏: 檢查代碼中是否有內(nèi)存分配后沒有釋放的情況。Valgrind是個(gè)好工具
    • 使用更高效的數(shù)據(jù)結(jié)構(gòu): 比如,用哈希表代替線性查找,用壓縮數(shù)據(jù)結(jié)構(gòu)減少內(nèi)存占用。
    • 優(yōu)化算法: 避免不必要的內(nèi)存復(fù)制,減少臨時(shí)變量的創(chuàng)建。
    • 使用內(nèi)存池: 減少頻繁的內(nèi)存分配和釋放操作。
  4. 限制進(jìn)程內(nèi)存使用:治標(biāo)之策

    可以使用ulimit命令限制進(jìn)程的內(nèi)存使用量。例如,ulimit -v 2000000限制進(jìn)程的虛擬內(nèi)存使用量為2GB。但這只是治標(biāo)之策,不能解決根本問題。

  5. 升級(jí)硬件:終極方案

    如果以上方法都無效,那就只能升級(jí)硬件了。加內(nèi)存條是最直接有效的辦法。

如何監(jiān)控Linux系統(tǒng)內(nèi)存使用情況?

監(jiān)控內(nèi)存使用情況是預(yù)防OOM錯(cuò)誤的有效手段。除了top命令,還可以使用free -m命令查看內(nèi)存使用情況。free -m會(huì)以MB為單位顯示內(nèi)存使用情況,包括總內(nèi)存、已用內(nèi)存、空閑內(nèi)存、Swap空間等。

更高級(jí)的監(jiān)控工具包括:

  • vmstat: 報(bào)告虛擬內(nèi)存統(tǒng)計(jì)信息。
  • sar: 收集、報(bào)告和保存系統(tǒng)活動(dòng)信息,包括內(nèi)存使用情況。
  • Grafana + Prometheus: 搭建一套完整的監(jiān)控系統(tǒng),可以實(shí)時(shí)監(jiān)控內(nèi)存使用情況,并設(shè)置告警。

OOM Killer是如何工作的?如何避免被它殺死?

OOM Killer會(huì)根據(jù)一個(gè)叫做oom_score的參數(shù)來選擇要?dú)⑺赖倪M(jìn)程。oom_score越高,被殺死的可能性越大。這個(gè)分?jǐn)?shù)會(huì)考慮進(jìn)程的內(nèi)存占用、運(yùn)行時(shí)間、用戶權(quán)限等因素。

如何避免被OOM Killer殺死?

  • 降低oom_score: 可以通過調(diào)整/proc//oom_adj或/proc//oom_score_adj文件來降低進(jìn)程的oom_score。例如,echo -17 > /proc//oom_score_adj可以將進(jìn)程的oom_score降到最低,使其幾乎不可能被OOM Killer殺死。但是,這樣做有風(fēng)險(xiǎn),如果該進(jìn)程真的導(dǎo)致了OOM,可能會(huì)導(dǎo)致系統(tǒng)崩潰。
  • 合理分配內(nèi)存: 盡量避免程序占用過多的內(nèi)存。
  • 使用cgroups: cgroups可以限制進(jìn)程的資源使用量,包括內(nèi)存。

如何分析OOM日志?

OOM Killer殺死進(jìn)程后,會(huì)在系統(tǒng)日志中留下記錄。這些日志通常包含被殺死的進(jìn)程ID、進(jìn)程名、內(nèi)存占用情況等信息。分析這些日志可以幫助我們找到導(dǎo)致OOM的原因。

日志通常位于/var/log/syslog或/var/log/kern.log文件中。可以使用grep命令過濾出OOM相關(guān)的日志。例如,grep “Out of memory” /var/log/syslog。

分析OOM日志需要一定的經(jīng)驗(yàn),但只要耐心分析,就能找到問題的根源。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊10 分享