当前位置: 首页 > 面试题库 >

Python subprocess.Popen错误,出现OSError:[Errno 12]在一段时间后无法分配内存

越国源
2023-03-14
问题内容

我有一个Python脚本,它每60秒执行一次,作为后台进程运行。其中一部分是对subprocess.Popen的调用,以获取ps的输出。

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

运行几天后,该呼叫出现以下错误:

getProcesses中的文件“ /home/admin/sd-agent/checks.py”,行436
__init__中的文件“ /usr/lib/python2.4/subprocess.py”,第533行
_get_handles中的文件“ /usr/lib/python2.4/subprocess.py”,行835
OSError:[Errno 12]无法分配内存

但是,服务器上free的输出为:

$ free -m
                  已使用的可用共享缓冲区总数
内存:894345549549 0 0 0
-/ +缓冲区/缓存:345549
掉期:0 0 0

我到处寻找问题,发现这篇文章说:

解决方案是向服务器添加更多交换空间。当内核分叉启动建模器或发现过程时,它首先确保在交换存储中有足够的空间来存储新过程(如果需要)。

我注意到上面的免费输出没有可用的交换。这可能是问题所在,并且/或者还有其他解决方案吗?

更新2009年8月13日
作为一系列监视功能的一部分,上述代码每60秒被调用一次。进程被守护,并使用sched安排检查。上述功能的特定代码为:

def getProcesses(self):
    self.checksLogger.debug('getProcesses: start')

    # Memory logging (case 27152)
    if self.agentConfig['debugMode'] and sys.platform == 'linux2':
        mem = subprocess.Popen(['free', '-m'], stdout=subprocess.PIPE).communicate()[0]
        self.checksLogger.debug('getProcesses: memory before Popen - ' + str(mem))

    # Get output from ps
    try:
        self.checksLogger.debug('getProcesses: attempting Popen')

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

    except Exception, e:
        import traceback
        self.checksLogger.error('getProcesses: exception = ' + traceback.format_exc())
        return False

    self.checksLogger.debug('getProcesses: Popen success, parsing')

    # Memory logging (case 27152)
    if self.agentConfig['debugMode'] and sys.platform == 'linux2':
        mem = subprocess.Popen(['free', '-m'], stdout=subprocess.PIPE).communicate()[0]
        self.checksLogger.debug('getProcesses: memory after Popen - ' + str(mem))

    # Split out each process
    processLines = ps.split('\n')

    del processLines[0] # Removes the headers
    processLines.pop() # Removes a trailing empty line

    processes = []

    self.checksLogger.debug('getProcesses: Popen success, parsing, looping')

    for line in processLines:
        line = line.split(None, 10)
        processes.append(line)

    self.checksLogger.debug('getProcesses: completed, returning')

    return processes

这是称为检查的较大类的一部分,该类在守护程序启动时初始化一次。

可以在http://github.com/dmytton/sd-
agent/blob/82f5ff9203e54d2adeee8cfed704d09e3f00e8eb/checks.py中
找到整个检查类,该类具有从442行定义的getProcesses函数。doChecks()从520行开始调用。


问题答案:

当您使用popen时,如果希望它关闭额外的文件描述符,则需要上交close_fds = True。

创建一个新管道,该管道出现在_get_handles函数中,从后向跟踪开始,它创建了2个文件描述符,但是您当前的代码永远不会关闭它们,并最终达到系统的最大fd限制。

不知道为什么收到的错误指示内存不足情况:它应该是文件描述符错误,因为的返回值pipe()有针对此问题的错误代码。



 类似资料:
  • 问题内容: 我刚从python移植了我的应用程序,所以Go有点新。看来我遇到了记忆问题。 它在ubuntu机器上运行。通过主管。 编辑: 设置解决问题 问题答案: 对于遇到此问题的其他人,这是golang问题中的相关近期问题 对于所有受影响的人,在Linux上得到适当修复之前的临时替代方法可以是以下之一: 启用无条件过量使用: 能够无条件过载:添加交换到你的主机,用它几乎永远不会被使用,但在计算参

  • 我正在用OpenFL开发一个android游戏。当我在手机上测试它时,它启动得很好。现在,如果我停用游戏应用程序,并在短时间后返回它,它显示黑屏不到一秒钟,然后返回游戏。 然而,如果游戏应用程序在后台停留大约10分钟,那么如果我再次打开它,它就会显示黑屏,然后游戏在等待15秒之后就会出现,或者它根本就不会出现--只是一个黑屏。(至此,既然我可以下拉通知栏,android就没有冻结了。) 游戏中也有

  • 我正在尝试运行下面的程序,在该程序中,我使用一个名为Reserve的函数动态地为变量分配内存。当我运行应用程序时,由于在一个单独的函数中为一个空指针分配内存,我会得到分段错误,但是如果我想在主函数中分配内存,我不会得到这个错误。那我做错了什么? 代码如下:

  • 我有一个简单的程序,应该打印今天的名字。它是工作的,但我做了get_query_result函数,然后它给了我一个分割错误。我看不出这里有什么错误,请帮帮我。

  • PHP间歇性地报告荒谬的分配错误。 致命错误:第0行中未知的134217728字节的允许内存大小已用尽 (尝试分配4348209864字节) 它试图分配超过4GB的内存。什么哪里是?它试图分配到哪里? 我没有在PHP代码中显式分配任何内存,也没有使用除股票PHP调用以外的任何东西。我看到我的PHP文件中的最后一行原始HTML(在我退出PHP块之后)被发出并在加载的页面中,因此问题似乎没有出现在我的

  • 我编写了一些逻辑,同时表示与exchange的近200个websocet连接。我使用第三方api,它基于org.eclipse.jetty.webSocket.api。我有一个我必须重写的方法。 我在stackoverflow上找到了这个问题,但我看不到清晰的答案。请帮忙,提前谢谢。