Memory leak with opencv Mat and std::queue
The camera records frames which is stored in a std::queue<cv::Mat> buffer
for further processing.
After the processing is done we want to pop the frame: buffer.pop()
. After this buffer.size()
shows that the element is truly popped from the container, but it is trapped in the memory (memory usage is constantly rising).
If I do the following:
cv::Mat current_frame;
while(recording)
{
current_frame = getLastFrame();
(*this->buffer).push(current_frame.clone());
}
then in the processing thread the memory is not released with (*this->buffer).pop()
instead constantly rising.
I have tried opencv's release()
on the matrix and also swap()
the queue with an empty queue without success.
I also tried to create a class object for the frame with destructor containing cv::Mat's release()
. Te realization of the class is the following:
_cameraframe.hpp_
class CameraFrame
{
public:
CameraFrame(const cv::Mat& frame);
~CameraFrame();
cv::Mat _frame;
};
_cameraframe.cpp_
#include "cameraframe.hpp"
CameraFrame::CameraFrame(const cv::Mat& frame)
{
//_frame = frame.clone();
_frame.create(frame.rows, frame.cols, frame.type());
std::memcpy(_frame.ptr(), frame.ptr(), 3 * frame.rows * frame.cols);
}
CameraFrame::~CameraFrame()
{
_frame.release();
std::cout << "OpenCV frame is released!" << std::endl;
}
If I run this code:
cv::Mat current_frame;
std::queue<CameraImage> buffer;
while(recording)
{
current_frame = getLastFrameFromCamera();
buffer.push(CameraImage(current_frame));
buffer.pop()
}
The same happens: The element is popped from the queue, but the memory is constantly rising (whatching it with linux's top
command) and after some time the system crashes. This indicates that the matrix is somehow trapped in memory and did not release.
__Edit__
_Minimal reproducible code_:
cv::Mat current_frame(500, 500, CV_16UC3);
std::queue<cv::Mat> buffer;
while(true)
{
buffer.push(current_frame.clone());
buffer.front().release();
buffer.pop();
}
Memory is linearly increasing and not released with OpenCV's release
and pop
ping from queue.
can you come up with a minimal, reproducable example ?
@berak For example this: