Open MahmoudAshraf97 opened 3 weeks ago
This is because av.audio.resampler.AudioResampler
uses av.filter.graph.Graph
, and obviously graphs require a circular reference which would create an object that is not deletable by traversing acyclic reference graphs. Because of it, while the AudioResampler
gets deallocated when it gets out of scope, Graph
does not.
It is not a bug, because it does not affect the program's correctness, and the author has relied on cpython's implementation of the cyclic garbage collector to clean up the resources. It would be a performance enhancement if the reference loop is eliminated.
@MahmoudAshraf97, please test again using https://github.com/PyAV-Org/PyAV/pull/1439/commits/851ff21b4dd607468bc544c6222980de17fdee01. It will not solve the issue completely, but it could reduce some of the memory footprint.
This is the result:
I guess the problem still exists, and since repeating the same experiment many times doesn't guarantee exact reproduction, I cant verify whether this is partially solved or not
Using large enough iteration will help to make the result somewhat deterministic.
In my machine (arm64 M2 Pro Darwin 14.4.1), with
delete=False, collect=False, n=200
;
Without applying the patch (left) I can see the gc periodically cleans the circular referenced objects and there seems to be some objects that cannot be recovered by gc.
After applying the patch (right) the memory graph is steadily increasing and no signs of visible gc activity. The graph could indicate a real leak though I haven't investigated it further. Overall the memory footprint seems to be significantly smaller.
@MahmoudAshraf97, can you try my patch again with delete=False, collect=False, n=200
and compare it with v12.1.0 or main?
@moonsikpark The Graph
object probably has a memory leak, and it certainly has it's own circular references.
Overview
I have a class that accepts audio inputs and resamples them as needed, the resampler parameters are different for each call so I can't create the resampler as a class member, anyways, after executing the function the resampler still leaves residuals in memory even if deleted
Expected behavior
memory usage should stay constant without having to run GC
Actual behavior
memory usage increases if GC is not run manually even if resampler object is deleted
Investigation
I ran the reproduction code to test three different cases:
Baseline:![image](https://github.com/PyAV-Org/PyAV/assets/32404268/9b3f7f2e-7b3d-4478-8e51-4b36d01f0c79)
delete=True
,collect=False
collect=True
Reproduction
Versions
Research
I have done the following:
Additional context
https://github.com/SYSTRAN/faster-whisper/issues/390 https://github.com/SYSTRAN/faster-whisper/pull/856/