I am searching for a memory leak in code of someone else. I found:
def current(self):
...
data = PyBuffer_New(buflen)
PyObject_AsCharBuffer(data, &data_ptr, &buflen)
...
return VideoFrame(data, self.frame_size, self.frame_mode,
timestamp=<double>self.frame.pts/<double>AV_TIME_BASE,
frameno=self.frame.display_picture_number)
cdef class VideoFrame:
def __init__(self, data, size, mode, timestamp=0, frameno=0):
self.data = data
...
In function current() is no free or similar, neither in VideoFrame. Is the PyBuffer automatically freed when the VideoFrame object gets deleted?
The answer is: "it depends; we don't have enough code to tell from your question." It's governed by what type you've told Cython that
PyBuffer_Newreturns. I'll give two simplified illustrating cases and hopefully you should be able to work it out for your more complicated case.If you tell Cython that it's a
PyObject*it has no innate knowledge of that type, and doesn't do anything to keep track of the memory:and the generated code for the loop pretty much looks like:
i.e. memory is being allocated but never freed. If you run
test()and look at a task manager you can see the memory usage jump up and not return.Alternatively, if you tell Cython it's an
objectthat lets Cython deal with it like any other Python object, and manage the reference count correctly:The generated code for the loop is then
Note the
DECREF, which will be where the object is deallocated. If you runtest()here you see no long-term jump in memory usage.It may be possible to jump between these two cases by using
cdeffor variable (for example in the definition ofVideoFrame). If they usePyObject*without carefulDECREFs then they're probably leaking memory...