Python子进程。Popen“ OSError:[Errno 12]无法分配内存”

python脚本使用sched模块每60秒运行一组类函数:


# sc is a sched.scheduler instance

sc.enter(60, 1, self.doChecks, (sc, False))

该脚本使用此处的代码作为守护进程运行。


doChecks的一部分调用的许多类方法使用子过程模块来调用系统函数,以获取系统统计信息:


ps = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE).communicate()[0]

在整个脚本崩溃并出现以下错误之前,它可以正常运行一段时间:


File "/home/admin/sd-agent/checks.py", line 436, in getProcesses

File "/usr/lib/python2.4/subprocess.py", line 533, in __init__

File "/usr/lib/python2.4/subprocess.py", line 835, in _get_handles

OSError: [Errno 12] Cannot allocate memory

脚本崩溃后,服务器上free -m的输出为:


$ free -m

                  total       used       free     shared     buffers    cached

Mem:                894        345        549          0          0          0

-/+ buffers/cache:  345        549

Swap:                 0          0          0

服务器正在运行CentOS 5.3。我无法在自己的CentOS盒子上或任何其他报告相同问题的用户上进行复制。


我已经尝试了许多方法来调试此问题,如原始问题中所建议的那样:


在Popen调用之前和之后记录free -m的输出。内存使用没有显着变化,即,随着脚本运行,内存不会逐渐耗尽。


我在Popen调用中添加了close_fds = True,但这没有什么不同-脚本仍然因相同的错误而崩溃。建议在这里和这里。


我检查了这所建议双方RLIMIT_DATA和RLIMIT_AS显示(-1,-1)的rlimits 这里。


一篇文章建议没有交换空间可能是原因,但是交换实际上是按需提供的(根据Web主机),这在这里也被认为是虚假的原因。


进程已关闭,因为这是使用.communicate()的行为,该行为由Python源代码和此处的注释支持。


整个检查都可以在GitHub上的第442行定义的getProcesses函数中找到。这由doChecks()从520行开始调用。


温温酱
浏览 2155回答 3
3回答

冉冉说

swap可能不是以前建议的红色鲱鱼。之前的python进程有多大ENOMEM?在内核2.6下,/proc/sys/vm/swappiness控制内核将如何积极地进行交换,并overcommit*归档内核可以眨眨一下头来分配多少内存以及如何精确分配内存。就像您的Facebook关系状态一样,这很复杂。...但是交换实际上是按需提供的(根据Web主机)...但不是根据free(1)命令的输出,该命令的输出不显示服务器实例识别的交换空间。现在,您的Web主机肯定比我对这个主题了解更多,但是我使用的虚拟RHEL / CentOS系统报告了可用于来宾OS的交换。改编Red Hat KB第15252条:只要匿名内存和系统V共享内存的总和小于RAM量的3/4,那么Red Hat Enterprise Linux 5系统就可以在没有交换空间的情况下运行良好。....内存小于或等于4GB的系统 [建议]至少具有2GB的交换空间。将您的/proc/sys/vm设置与普通的CentOS 5.3安装进行比较。添加交换文件。棘轮下来swappiness,看看你是否再活下去。
打开App,查看更多内容
随时随地看视频慕课网APP