歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> 關於Linux >> Ubuntu Server內存溢出:Out of memory

Ubuntu Server內存溢出:Out of memory

日期:2017/3/3 15:57:40   编辑:關於Linux

環境:

Ubuntu Server 12.04 i686

問題描述:

24G內存,空閒的有20G左右。但是內核老是報這個,動不動就殺程序 
     
Jul  6 13:12:44 00098 kernel: [3112325.883069] Out of memory: Kill process 2249 (nginx) score 1 or sacrifice child 
Jul  6 13:12:44 00098 kernel: [3112325.922795] Killed process 2831 (nginx) total-vm:21772kB, anon-rss:11048kB, file-rss:916kB 
     
Jul  6 12:43:18 00098 kernel: [3110562.214498] snmpd invoked oom-killer: gfp_mask=0x840d0, order=0, oom_adj=0, oom_score_adj=0
Jul  6 12:43:18 00098 kernel: [3110562.214502] snmpd cpuset=/ mems_allowed=0
     
Jul  6 12:49:57 00098 kernel: [3110960.995962] Out of memory: Kill process 1858 (mysqld) score 1 or sacrifice child 
Jul  6 12:49:57 00098 kernel: [3110961.032675] Killed process 1858 (mysqld) total-vm:140652kB, anon-rss:15492kB, file-rss:6100kB 
Jul  6 12:49:57 00098 kernel: [3110961.103870] init: mysql main process (1858) killed by KILL signal 
Jul  6 12:49:57 00098 kernel: [3110961.103899] init: mysql main process ended, respawning

真的是很郁悶啊,搭建了一個Cacti,系統上剛好有Nginx,所以就用了Nginx,要提供php的支持,還必須安裝php5-fpm,安裝完成後,登陸上Cacti,過一會兒一刷新,就掛掉了,剛開始還以為是Nginx掛掉了,就沒在意,過一會兒,監控報警說Nginx掛掉了,看了下Nginx的日志,沒發現異常,今天又發現MySQL掛了,這下蛋疼了,怎麼程序動不動就掛呢!仔細分析了一下日志,發現內核報了以上內容,OOM-KILLER這個東西,動不動就殺程序,但是內存並沒有滿,空的很。

然後網上找了下資料,32位的系統,如果Low-memory耗盡,就會導致這個問題的出現。看了一下Low-memory,確實很少!

通常,在大內存(6Gb+)服務器上,out of memory killer (oom-killer)也會殺死進程。在很多case中,人們都困惑地報告說還有剩余內存的情況下,為何oom-killer還會殺死進程?現象是在 /var/log/messages 日志中,有如下信息:

Out of Memory: Killed process [PID] [process name].

在我自己的case中,我在VMware中升級了各個RHEL3到RHEL4,有1個16Gb內存的服務器,還是會被oom-killer殺死進程。不用說,這非常令人沮喪。

事實證明,這個問題的原因是low memory耗盡。引用Tom的話“內核使用low memory來跟蹤所有的內存分配,這樣的話一個16GB內存的系統比一個4GB內存的系統,需要消耗更多的low memory,可能有4倍之多。這種額外的壓力從你剛啟動系統那一刻就開始存在了,因為內核結構必須為潛在的跟蹤四倍多的內存分配而調整大小

說白了 OOM Killer 就是一層保護機制,用於避免 Linux 在內存不足的時候不至於出太嚴重的問題,把無關緊要的進程殺掉,有些壯士斷腕的意思。

先要學習點老知識,在 32 位CPU 架構下尋址是有限制的。Linux 內核定義了三個區域:

# DMA: 0x00000000 - 0x00999999 (0 - 16 MB)

# LowMem: 0x01000000 - 0x037999999 (16 - 896 MB) - size: 880MB

# HighMem: 0x038000000 - <硬件特定>

LowMem 區 (也叫 NORMAL ZONE ) 一共 880 MB,而且不能改變(除非用 hugemem 內核)。對於高負載的系統,就可能因為 LowMem 利用不好而引發 OOM Killer 。一個可能原因是 LowFree 太少了,另外一個原因是 LowMem 裡都是碎片,請求不到連續的內存區域

有兩種方法查看 low memory 和 high memory 的狀態:

# egrep 'High|Low' /proc/meminfo 
HighTotal:     5111780 kB 
HighFree:         1172 kB 
LowTotal:       795688 kB 
LowFree:         16788 kB 
     
# free -lm 
             total       used       free     shared    buffers     cached 
Mem:          5769       5751         17          0          8       5267
Low:           777        760         16          0          0          0
High:         4991       4990          1          0          0          0
-/+ buffers/cache:        475       5293
Swap:         4773          0       4773

當low memory耗盡,不管high memory剩余多少,oom-killer都開始殺死進程,以保持系統的正常運轉。

有兩種方法可以解決這個問題

1、如果可能,請升級到64位系統。

URL:http://www.bianceng.cn/OS/Linux/201410/46052.htm

這是最好的解決辦法,因為所有的內存都將成為low memory。如果你在這種情況下耗盡了low memory,那就真的是out of memory了。

2、如果受限於必須使用32位系統,最好的解決辦法是使用hugemem內核。

這種內核以不同的方式分割low/high memory,而且在大多數情況下會提供足夠多的low memory到high memory的映射。在大多數案例中,這是一個很簡單的修復方法:安裝hugemem kernel RPM包,然後重啟即可。

如果運行hugemem內核也不可能,你可以嘗試將/proc/sys/vm/lower_zone_protection 的值設置為250甚至更多。這將讓內核願意保護low memory,從而在分配內存時多考慮從high memory分配。據我所知,此選項從2.6.x內核才開始可用。必要的是,您可能需要通過一些實驗來找到您系統環境中最適合的值。可以使用下面方法快速的設置和檢查改值:

# cat /proc/sys/vm/lower_zone_protection

# echo "250" > /proc/sys/vm/lower_zone_protection

在 /etc/sysctl.conf 中加入設置,以便啟動就生效:

vm.lower_zone_protection = 250

作為最後的努力,你可以關閉oom-killer。這個選項可以導致系統掛起,所以請小心使用(風險自負)!

查看當前oom-killer的狀態:

# cat /proc/sys/vm/oom-kill

關閉/打開oom-killer:

# echo "0" > /proc/sys/vm/oom-kill

# echo "1" > /proc/sys/vm/oom-kill

當進程該被oom-killer殺死卻沒有被殺死時,相關信息會記錄到 /var/log/messages:

"Would have oom-killed but /proc/sys/vm/oom-kill is disabled"

Copyright © Linux教程網 All Rights Reserved