Skip to content

Break reference cycle in StreamContainer.get()#2221

Merged
WyattBlue merged 1 commit intoPyAV-Org:mainfrom
lgeiger:decode-reference-cycle
Apr 2, 2026
Merged

Break reference cycle in StreamContainer.get()#2221
WyattBlue merged 1 commit intoPyAV-Org:mainfrom
lgeiger:decode-reference-cycle

Conversation

@lgeiger
Copy link
Copy Markdown
Contributor

@lgeiger lgeiger commented Apr 2, 2026

StreamContainer.get() defines a process function which binds self. This causes a reference cycle putting strain on the Garbage collector. This can be reproduced with the following code:

import gc
import av
from tests.common import fate_suite


def demux(video):
    with av.open(video) as container:
        for packet in container.demux(video=0):
            pass


video = fate_suite("h264/interlaced_crop.mp4")
gc.collect()
gc.disable()
demux(video)
print("GC collected:", gc.collect())
version GC collected objects
main 399
This PR 0

We could also break this reference cycle by setting process = None after it's use in StreamContainer.get() but I think moving it into a separate method which yields is cleaner.

@oakaigh can you check whether this fixes #2219 for you?

@lgeiger lgeiger changed the title Break reference cycle StreamContainer.get() Break reference cycle in StreamContainer.get() Apr 2, 2026
@WyattBlue WyattBlue merged commit 74534ec into PyAV-Org:main Apr 2, 2026
8 checks passed
@lgeiger lgeiger deleted the decode-reference-cycle branch April 2, 2026 15:00
@oakaigh
Copy link
Copy Markdown

oakaigh commented Apr 3, 2026

@lgeiger Don't have the bandwidth to test this right now; In the meantime, wouldn't it be better to add the code to the tests and run it through CI?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Memory leaks when containers are opened and decoded in a loop

3 participants