【转】Linux 报Out of memory(转) 错误的解决方法

日志查看: cat /var/log/messages

from:http://space.itpub.net/8541492/viewspace-758561

环境:

Ubuntu Server 12.04 i686

问题描述:

 
 
  1. 24G内存,空闲的有20G左右。但是内核老是报这个,动不动就杀程序
  2. Jul 6 13:12:44 00098 kernel: [3112325.883069] Out of memory: Kill process 2249 (nginx) score 1 or sacrifice child
  3. Jul 6 13:12:44 00098 kernel: [3112325.922795] Killed process 2831 (nginx) total-vm:21772kB, anon-rss:11048kB, file-rss:916kB
  4. 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
  5. Jul 6 12:43:18 00098 kernel: [3110562.214502] snmpd cpuset=/ mems_allowed=0
  6. Jul 6 12:49:57 00098 kernel: [3110960.995962] Out of memory: Kill process 1858 (mysqld) score 1 or sacrifice child
  7. Jul 6 12:49:57 00098 kernel: [3110961.032675] Killed process 1858 (mysqld) total-vm:140652kB, anon-rss:15492kB, file-rss:6100kB
  8. Jul 6 12:49:57 00098 kernel: [3110961.103870] init: mysql main process (1858) killed by KILL signal
  9. 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 内核定义了三个区域:


 
 
  1. # DMA: 0x00000000 - 0x00999999 (0 - 16 MB)
  2. # LowMem: 0x01000000 - 0x037999999 (16 - 896 MB) - size: 880MB
  3. # HighMem: 0x038000000 - <硬件特定>

LowMem 区 (也叫 NORMAL ZONE ) 一共 880 MB,而且不能改变(除非用 hugemem 内核)。对于高负载的系统,就可能因为 LowMem 利用不好而引发 OOM Killer 。一个可能原因是 LowFree 太少了,另外一个原因是 LowMem 里都是碎片,请求不到连续的内存区域

有两种方法查看 low memory 和 high memory 的状态:

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

当low memory耗尽,不管high memory剩余多少,oom-killer都开始杀死进程,以保持系统的正常运转。

有两种方法可以解决这个问题

1、如果可能,请升级到64位系统。

这是最好的解决办法,因为所有的内存都将成为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内核才开始可用。必要的是,您可能需要通过一些实验来找到您系统环境中最适合的值。可以使用下面方法快速的设置和检查改值:

 
 
  1. # cat /proc/sys/vm/lower_zone_protection
  2. # echo "250" > /proc/sys/vm/lower_zone_protection

在 /etc/sysctl.conf 中加入设置,以便启动就生效:

vm.lower_zone_protection = 250

作为最后的努力,你可以关闭oom-killer。这个选项可以导致系统挂起,所以请小心使用(风险自负)!

查看当前oom-killer的状态:

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

关闭/打开oom-killer:

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

当进程该被oom-killer杀死却没有被杀死时,相关信息会记录到 /var/log/messages:

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

### Docker 容器启动时 OCI 运行时创建失败问题分析 当遇到 `docker: Error response from daemon: failed to create shim task: OCI runtime create failed` 的错误时,通常表明容器初始化过程中出现了问题。以下是可能的原因及其解决方案: #### 1. NVIDIA GPU 驱动程序配置不正确 如果正在尝试使用 NVIDIA GPU 支持的容器化应用,则可能是由于 NVIDIA 驱动未正确安装或配置引起的。错误日志显示了以下关键信息: > `nvidia-container-cli: initialization error: driver rpc error: timed out` 这表示 NVIDIA 容器工具无法成功连接到 GPU 驱动程序[^1]。可以按照以下方法排查并解决问题: - **验证驱动版本**:确认已安装最新版的 NVIDIA 驱动,并满足当前使用的 CUDA 版本需求。 - **重新安装 nvidia-docker2 插件**:卸载现有插件后重试安装,确保兼容性。 ```bash # 卸载旧版本 sudo apt-get purge -y nvidia-docker* # 添加官方仓库并更新 distribution=$(. /etc/os-release;echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list sudo apt-get update && sudo apt-get install -y nvidia-docker2 ``` #### 2. 文件系统挂载冲突 某些情况下,容器内的文件系统挂载操作可能会因权限不足或其他原因而失败。例如: > `mount error: mount operation failed` 此错误提示文件系统挂载存在问题[^2]。建议检查宿主机上的磁盘空间、SELinux 设置以及是否有重复挂载点干扰正常流程。 #### 3. 缺失依赖库 对于特定场景下的运行环境缺失必要动态链接库的情况,比如缺少 `libseccomp.so.2` 导致加载失败的问题,可以通过复制相应文件至目标路径解决[^3]: ```bash find / -name "libseccomp.so*" 2>/dev/null cp /path/to/found/library /usr/lib64/ ldconfig ``` #### 4. runC 执行机制异常 作为底层支持组件之一,runC 负责实际创建和管理容器实例。任何关于它的崩溃都应仔细审查是否存在 bug 或者不当参数传递情况。回顾 runC 历史演进可知它主要基于 libcontainer 实现基本功能集[^4]。因此升级到稳定版本或者调整相关选项或许有助于缓解此类状况。 --- ### 总结 针对上述提到的各种可能性逐一排除直至找到根本诱因为止。务必保持操作系统补丁级别最新状态同时参照社区反馈积极寻求帮助文档指导完成修复工作。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值