【问题标题】:OSError: [Errno 12] Cannot allocate memory from python subprocess.callOSError:[Errno 12] 无法从 python subprocess.call 分配内存
【发布时间】:2013-08-01 11:41:07
【问题描述】:

我已经阅读了几篇关于这个问题的类似帖子,但似乎没有一个能直接帮助我。如果这实际上是重复的帖子,请引导我到包含解决方案的线程!

我正在保存一堆图像,然后使用 subprocess.call 对它们调用 ffmpeg。我为不同图像的集合做了几次。这基本上就是我正在做的事情:

from subprocess import call
for video in videos:
  call(['ffmpeg', ..., '-i', video, video+'.mp4')])

单独来看,这很好用。但是,当我在这些调用之前还完成了一些其他处理时(不在循环内,实际上只是在循环开始之前将值保存在内存中),它在制作了几个视频后因内存错误而崩溃(实际上是在制作最后一个视频时)一)。根据this comment, subprocess.call 分叉/克隆当前进程,这似乎意味着它请求的内存分配等于我当前在内存中的内存量,这对于我想要在调用中做的事情似乎有点过头了ffmpeg。

如何在不要求分配不必要的内存量的情况下从 python 中调用 ffmpeg?

【问题讨论】:

    标签: python linux memory subprocess popen


    【解决方案1】:

    虽然 subprocess.call 确实 fork 进程,并且这个子进程确实有自己的内存空间,最初与父进程(您的 python 程序)相同,但现代操作系统将使用copy-on-write memory。 fork 进程的内存开销最初是比较小的,只需要内核中的几 KB 内存用于进程记帐。直到子进程开始对其内存进行更改,才需要额外的内存。

    在 fork 之后,由 subprocess.call 产生的子进程将调用其中一个 exec 系统调用,它将 ffmpeg 加载到内存中并开始执行它。

    此外,fork 通常是在 POSIX 系统上创建新进程的唯一机制 (see here),所以我认为 subprocess.call 实现的 fork-then-exec 序列没有替代方案。

    您可以尝试通过straceValgrind 运行您的程序,以查看究竟是哪个系统调用没有获得它所请求的内存。这可以帮助您确定如何降低内存要求。

    【讨论】:

    • 这里的答案简洁明了:子进程fork进程,内存可以增加。这是一个更复杂的 SO Q&A,也可能会有所帮助:stackoverflow.com/questions/1367373/… 向遇到此问题的人提供更多详细信息
    【解决方案2】:

    我今天遇到了同样的问题,我只是使用 os 解决了这个问题:

    import os
    for video in videos:
        job = ' ffmpeg ' + ... + ' -i ' + video + '.mp4'
        os.system( job )
    

    【讨论】:

      猜你喜欢
      • 2010-11-24
      • 2015-05-04
      • 1970-01-01
      • 2017-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-16
      • 1970-01-01
      相关资源
      最近更新 更多