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行开始调用。
冉冉说