Skip to content

Memory leak if stream is not explicitly closed #1117

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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