草庐IT

Out of memory

gm100861 2023-03-28 原文
环境:

Ubuntu Server 12.04  i686

问题描述:

  1. 24G内存,空闲的有20G左右。但是内核老是报这个,动不动就杀程序 
  2.  
  3. Jul  6 13:12:44 00098 kernel: [3112325.883069] Out of memory: Kill process 2249 (nginx) score 1 or sacrifice child 
  4. Jul  6 13:12:44 00098 kernel: [3112325.922795] Killed process 2831 (nginx) total-vm:21772kB, anon-rss:11048kB, file-rss:916kB 
  5.  
  6. Jul  6 12:43:18 00098 kernel: [3110562.214498] snmpd invoked oom-killer: gfp_mask=0x840d0order=0oom_adj=0oom_score_adj=0 
  7. Jul  6 12:43:18 00098 kernel: [3110562.214502] snmpd cpuset=/ mems_allowed=0 
  8.  
  9. Jul  6 12:49:57 00098 kernel: [3110960.995962] Out of memory: Kill process 1858 (mysqld) score 1 or sacrifice child 
  10. Jul  6 12:49:57 00098 kernel: [3110961.032675] Killed process 1858 (mysqld) total-vm:140652kB, anon-rss:15492kB, file-rss:6100kB 
  11. Jul  6 12:49:57 00098 kernel: [3110961.103870] init: mysql main process (1858) killed by KILL signal 
  12. 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.  
  3. # LowMem: 0x01000000 - 0x037999999 (16 - 896 MB) - size: 880MB 
  4.  
  5. # 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.  
  7. # free -lm 
  8.              total       used       free     shared    buffers     cached 
  9. Mem:          5769       5751         17          0          8       5267 
  10. Low:           777        760         16          0          0          0 
  11. High:         4991       4990          1          0          0          0 
  12. -/+ buffers/cache:        475       5293 
  13. 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"

 

 

有关Out of memory的更多相关文章

  1. android - 解析大文件 - OutOfMemory - Android - 2

    我正在尝试在android中解析一个大文件。xml文件大小超过2Mb。我正在使用这段代码:DocumentBuilderFactoryfactory=DocumentBuilderFactory.newInstance();DocumentBuilderdb=factory.newDocumentBuilder();InputSourceinStream=newInputSource();inStream.setCharacterStream(newStringReader(XMLResponse));Documentdoc=db.parse(inStream);我遇到了一个内存不足错

  2. c# - XmlDocument.Save OutOfMemory 异常 - 2

    我一直在使用这个方便的功能来“美化”一个xml文档,以便使用缩进和换行符来格式化它。但是对于更大的文档(~1MB),出于某种原因,我在doc.Save(writer)处得到了OutOfMemoryException。我该如何解决这个问题?publicstaticstringBeautifyXmlDocument(XmlDocumentdoc){MemoryStreamsb=newMemoryStream();XmlWriterSettingss=newXmlWriterSettings();s.Indent=true;s.IndentChars="";s.NewLineChars="\

  3. php - 在 OutOfMemory 异常时让 PHP 转储堆 - 2

    我目前正在调试一个经常遇到OutOfMemory异常的脚本。它作为cronjob运行并且通常运行良好,但是当cronjob有一段时间没有运行时(无论出于何种原因)脚本必须处理许多排队的元素并将遇到OutOfMemory异常。通过检查代码,我无法发现问题。我相信其中一个迭代函数调用可能会泄漏内存,但我不确定是哪一个以及在哪里。当发生OutOfMemory异常时,是否可以选择让PHP转储堆?我也许可以从那里发现问题(很有可能)。 最佳答案 虽然我找不到“异常时转储堆”选项,但我确实找到了get_defined_vars()如果从全局范围

  4. java - JVM 在 gc 期间抛出 OutOfMemory,尽管还有足够的内存 - 2

    我将我的java应用程序配置为使用5G内存。我突然遇到了OutOfMemory。我检查了gc日志,发现剩余内存充足:年轻代占用4%分配空间,tenure代占用5%,perm代占用43%。我很困惑为什么JVM在gc时间抛出OutOfMemory。有谁知道为什么会这样?非常感谢您的帮助。JVM内存和gc设置:-server-Xms5g-Xmx5g-Xss256k-XX:NewSize=2g-XX:MaxNewSize=2g-XX:+UseParallelOldGC-XX:+UseTLAB-XX:SurvivorRatio=8-XX:TargetSurvivorRatio=90-XX:+Di

  5. java - ActiveMQ OutOfMemory 无法创建更多线程 - 2

    我正在模拟服务器过载,但出现此错误:java.lang.OutOfMemoryError:unabletocreatenewnativethread我读过这个页面http://activemq.apache.org/javalangoutofmemory.html,我可以增加内存大小。但是我该怎么做呢?我需要修改哪个文件?我尝试通过bin/activemq脚本传递参数,但没有成功。 最佳答案 您的案例对应于massivenumberofthreads。有3种方法可以解决:减少线程数(即文档中的-Dorg.apache.activem

  6. java - 尝试更新我的 Intellij 时出现 OutOfMemory 错误 - 2

    我正在尝试将IntelliJIDEA从版本141.177更新到141.178。当更新下载所有需要的文件并开始更新时,我收到此错误:Temp.directory:/tmpjava.lang.OutOfMemoryError:Javaheapspaceatie.wombat.jbdiff.JBPatch.bspatch(JBPatch.java:91)atcom.intellij.updater.BaseUpdateAction.applyDiff(BaseUpdateAction.java:112)atcom.intellij.updater.UpdateAction.doApply(U

  7. c++ - 为什么我得到 E_OUTOFMEMORY? - 2

    出于某种原因,下面的代码会给我一个内存不足的错误。我错过了什么?for(intn=0;ndevice_ptr->CreateTexture2D(&texture_desc,nullptr,&target_d3d_ptr);if(FAILED(hr))throwruntime_error(_com_error(hr).ErrorMessage());target_d3d_ptr->Release();} 最佳答案 只是一个想法,但你有没有考虑过这个:1920*1080*32位=8294400字节现在,8294400字节x485纹理=3

  8. java - 如何在 Java 内存密集型应用程序中避免 OutOfMemory 异常? - 2

    我们开发了一个java应用程序,其主要目标是读取文件(输入文件)、处理它并将其转换为一组输出文件。(我已经对我们的解决方案进行了一般性描述,以避免不相关的细节)。当输入文件为4GB,内存设置为-Xms4096m-Xmx16384m,32GBRAM时,此程序运行良好现在我们需要使用大小为130GB的输入文件运行我们的应用程序。我们使用具有250GBRAM且内存设置为-Xms40g-Xmx200g(也尝试了其他几种变体)的linux机器来运行应用程序并遇到OutOfMemory异常。在我们项目的这个阶段,很难考虑重新设计代码以适应hadoop(或其他大型数据处理框架),而且我们目前可以承受

  9. android - Recycler View 中的 OutOfMemory 错误 - 2

    我正在制作一个简单的应用程序,它有一个带有交错布局的recyclerview在PHP脚本的帮助下使用Volley库从服务器加载数据当我单击RecyclerView中的项目时,我的应用程序崩溃并显示以下错误日志。此外,当我查看内存日志时,应用程序正在使用大量内存来将数据从服务器加载到recyclerViewLog//应用启动I/Choreographer:Skipped189frames!Theapplicationmaybedoingtoomuchworkonitsmainthread.I/art:BackgroundpartialconcurrentmarksweepGCfreed3

  10. Android Google Maps API V2 OutOfMemory 异常 - 2

    我有数据ListView,每个项目都会打开一个View,其中嵌入了map。该map的目的是显示单个标记。代码运行良好,但如果我有很多列表项(50+),来回循环会导致应用程序抛出OutOfMemory异常。谁能帮我理解我在这里做错了什么。我猜我的map初始化逻辑中有问题导致了这个问题。我正在努力解决这个问题。publicclassDetailViewextendsFragmentimplementsOnInfoWindowClickListener{privateMapViewmMapView;privateGoogleMapgoogleMap;@OverridepublicViewon

随机推荐