Memory leak with opencv Mat and std::queue

asked 2019-03-29 09:28:35 -0600

t3rb3d gravatar image

updated 2019-04-01 02:45:12 -0600

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 popping from queue.

edit retag flag offensive close merge delete

Comments

can you come up with a minimal, reproducable example ?

berak gravatar imageberak ( 2019-03-29 13:53:38 -0600 )edit

@berak For example this:

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();
}
t3rb3d gravatar imaget3rb3d ( 2019-04-01 01:19:41 -0600 )edit