You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用FFmpeg作为Python子进程读取视频帧到Numpy数组的内存泄漏排查

内存泄漏问题分析与修复

核心泄漏点

  • 未处理ffmpeg的stderr输出:pipe_thread中仅调用pipe.stderr.flush()但未实际读取stderr内容,ffmpeg会持续向stderr输出日志,这些数据会在缓冲区中不断累积,导致内存占用逐步上升。subprocess的管道缓冲区若不主动读取,数据会一直被Python进程持有,无法被垃圾回收。
  • numpy数组重复创建:每次循环里self.image = np.frombuffer(...)都会生成新的numpy数组,旧数组虽会被GC回收,但频繁创建新对象可能导致回收延迟,加剧内存占用问题。

修复方案

1. 读取并丢弃stderr内容

替换原代码中pipe.stderr.flush()的逻辑,主动读取stderr的所有可用内容并丢弃,避免缓冲区堆积:

# 替换原pipe.stderr.flush()
# 读取stderr内容并丢弃
while pipe.stderr.peek():
    pipe.stderr.readline()

2. 复用numpy数组,减少对象创建

初始化时创建的self.image可以复用,无需每次赋值新数组,直接修改已有数组的内容:

# 替换原self.image = np.frombuffer(...)
data = pipe.stdout.read(self.H * self.W * self.P)
if len(data) == self.H * self.W * self.P:
    self.image[:] = np.frombuffer(data, dtype='uint8').reshape((self.H, self.W, self.P))
    self.flag = True

3. 完善子进程清理逻辑

终止子进程后调用wait(),确保子进程完全退出,避免残留系统资源:

if len(data) < self.H * self.W * self.P: # 视频结束,重新加载
    pipe.terminate()
    pipe.wait() # 等待子进程彻底退出
    pipe = None

修复后的pipe_thread完整代码

def pipe_thread(self):
    pipe = None
    while not self.kill_thread:
        st_tm = time.time()
        if pipe is None:
            pipe = subprocess.Popen(self.command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=-1)
        data = pipe.stdout.read(self.H * self.W * self.P)
        pipe.stdout.flush()
        # 读取并丢弃stderr内容
        while pipe.stderr.peek():
            pipe.stderr.readline()
        if len(data) < self.H * self.W * self.P: # 视频结束,重新加载
            pipe.terminate()
            pipe.wait()
            pipe = None
        else:
            self.image[:] = np.frombuffer(data, dtype='uint8').reshape((self.H, self.W, self.P))
            self.flag = True
        step = time.time() - st_tm
        time.sleep(max(0.04 - step, 0.0))
    if pipe is not None:
        pipe.terminate()
        pipe.wait()
        pipe = None

内容的提问来源于stack exchange,提问作者paddyg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 05:26:01