Skip to content

Memory leak if stream is not explicitly closed #1117

@hmaarrfk

Description

@hmaarrfk

Overview

I think there is a memory leak that occurs if you don't explicitly close a container or stream.

WyattBlue: Stream only. Other leaks have been fixed in 12.x

I'm still trying to drill the problem down, but I think I have a minimum reproducing example that I think is worthwhile to share at this stage.

WyattBlue: Cleaned up for my convenience

It seems that __dealloc__ isn't called as expected maybe??? https://github.com/PyAV-Org/PyAV/blob/main/av/container/input.pyx#L88

WyattBlue: No

import os

import av
import numpy as np
import psutil
from matplotlib import pyplot as plt
from tqdm import tqdm


def main():
    data = np.ones((256, 256, 3), dtype="uint8")

    with av.open("video.mp4", "w") as container:
        stream = container.add_stream("libopenh264", rate=30)
        stream.height = data.shape[0]
        stream.width = data.shape[1]
        stream.pix_fmt = "yuv420p"

        for j in tqdm(range(100), leave=False):
            frame = av.VideoFrame.from_ndarray(data)
            for packet in stream.encode(frame):
                container.mux(packet)
        stream.close()

    virtual_memory = []
    memory_used = []

    for j in tqdm(range(10000)):
        with av.open("video.mp4", "r") as container:
            stream = container.streams.video[0]
            for packet in container.demux(stream):
                stream.decode(packet)

            process = psutil.Process(os.getpid())
            memory_info = process.memory_info()
            memory_used.append(memory_info.rss)
            virtual_memory.append(memory_info.vms)
                
            # Explicitly call close to reduce the memory leak.
            # stream.close()

    m_used = np.asarray(memory_used)
    v_used = np.asarray(virtual_memory)
    plt.loglog(np.arange(1, len(m_used)), m_used[1:] - m_used[0], label="Memory Used")
    plt.ylabel("Memory Usage (Bytes)")
    plt.xlabel("Iteration (count)")
    plt.legend()
    plt.show()


if __name__ == "__main__":
    main()

image

Expected behavior

That the memory be cleared. If I add the close calls to the loop I get.
image

Versions

  • OS: Ubuntu 22.10 + conda + conda-forge
  • PyAV runtime:
python -m av --version
PyAV v10.0.0.post2
library configuration: --prefix=/home/mark/mambaforge/envs/mcam_dev --cc=/home/conda/feedstock_root/build_artifacts/ffmpeg_1674566195805/_build_env/bin/x86_64-conda-linux-gnu-cc --cxx=/home/conda/feedstock_root/build_artifacts/ffmpeg_1674566195805/_build_env/bin/x86_64-conda-linux-gnu-c++ --nm=/home/conda/feedstock_root/build_artifacts/ffmpeg_1674566195805/_build_env/bin/x86_64-conda-linux-gnu-nm --ar=/home/conda/feedstock_root/build_artifacts/ffmpeg_1674566195805/_build_env/bin/x86_64-conda-linux-gnu-ar --disable-doc --disable-openssl --enable-demuxer=dash --enable-hardcoded-tables --enable-libfreetype --enable-libfontconfig --enable-libopenh264 --enable-gnutls --enable-libmp3lame --enable-libvpx --enable-pthreads --enable-vaapi --disable-gpl --enable-libaom --enable-libsvtav1 --enable-libxml2 --enable-pic --enable-shared --disable-static --enable-version3 --enable-zlib --enable-libopus --pkg-config=/home/conda/feedstock_root/build_artifacts/ffmpeg_1674566195805/_build_env/bin/pkg-config
library license: LGPL version 3 or later
libavcodec     59. 37.100
libavdevice    59.  7.100
libavfilter     8. 44.100
libavformat    59. 27.100
libavutil      57. 28.100
libswresample   4.  7.100
libswscale      6.  7.100
  • FFmpeg:
ffmpeg version 5.1.2 Copyright (c) 2000-2022 the FFmpeg developers
built with gcc 11.3.0 (conda-forge gcc 11.3.0-19)
configuration: --prefix=/home/conda/feedstock_root/build_artifacts/ffmpeg_1674566195805/_h_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_plac --cc=/home/conda/feedstock_root/build_artifacts/ffmpeg_1674566195805/_build_env/bin/x86_64-conda-linux-gnu-cc --cxx=/home/conda/feedstock_root/build_artifacts/ffmpeg_1674566195805/_build_env/bin/x86_64-conda-linux-gnu-c++ --nm=/home/conda/feedstock_root/build_artifacts/ffmpeg_1674566195805/_build_env/bin/x86_64-conda-linux-gnu-nm --ar=/home/conda/feedstock_root/build_artifacts/ffmpeg_1674566195805/_build_env/bin/x86_64-conda-linux-gnu-ar --disable-doc --disable-openssl --enable-demuxer=dash --enable-hardcoded-tables --enable-libfreetype --enable-libfontconfig --enable-libopenh264 --enable-gnutls --enable-libmp3lame --enable-libvpx --enable-pthreads --enable-vaapi --disable-gpl --enable-libaom --enable-libsvtav1 --enable-libxml2 --enable-pic --enable-shared --disable-static --enable-version3 --enable-zlib --enable-libopus --pkg-config=/home/conda/feedstock_root/build_artifacts/ffmpeg_1674566195805/_build_env/bin/pkg-config
libavutil      57. 28.100 / 57. 28.100
libavcodec     59. 37.100 / 59. 37.100
libavformat    59. 27.100 / 59. 27.100
libavdevice    59.  7.100 / 59.  7.100
libavfilter     8. 44.100 /  8. 44.100
libswscale      6.  7.100 /  6.  7.100
libswresample   4.  7.100 /  4.  7.100

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions