Search code examples
c++multithreadingopencvstdvectorstdthread

Memory leak with OpenCV and std:thread


I have a rather really simple piece of code, I generate some cv::Mat images inside a function (myFunction) and fill an std::vector with them, whilst the vector is been filled the memory usage increase and after the vector goes out of scope the memory it used is freed as expected.

But for some reason if I execute cv::cvtColor before adding the Mat to the vector, the memory is not freed after the vector goes out of scope. Also, if I iterate over the vector and execute the cv::imwrite function before the vector goes out of scope the memory is not freed either.

These two problems only occur if I execute myFunction in an std::thead, if I don't use std:thread there is no memory leak at all.

This is my code:


void myFunction(){;

  int x = 0;
  std::vector<cv::Mat> myvector;

  while(x < 1000){
    cv::Mat oImage(1000, 2000, CV_8UC3, cv::Scalar(255,0,255));
    //cv::cvtColor(oImage,oImage,cv::COLOR_BGR2RGB);  IF I UNCOMMENT THIS LINE THE LEAK OCCURS WHEN USING STD:THREAD
    myvector.push_back(oImage);
    x++;
  }
  /* ALSO IF I DON'T EXECUTE cvtColor BUT I UNCOMMENT THESE 4 LINES THE LEAK ALSO OCCURS WHEN USING STD::THREAD
  int _size = myvector.size();
  for(int i = 0; i < _size; i++){
     imwrite("/home/admin/test/"+std::to_string(i)+".jpg", myvector[i]);
  }
  */

  myvector.clear();

};


int main(int argc, char** argv)
{

   int y =0;
   while(y<20){
      std::thread t(myFunction);
      t.join();
      //myFunction(); //NO PROBLEM OCCURS IF I JUST CALL THIS FUNCTION WITHOUT USING STD::THREAD
     std::cout << "out of scope"; //HERE THE MEMORY SHOULD HAVE BEEN FREED
      getchar();
   }
   return 0;
}

I'm using OpenCV 4.7, I think there was a problem with opencv and thread when using version 3.2.0, but it should be fix right now.


Solution

  • I've made a minimal reproducible example using valgrind and your observed memory leak is most probably related to Thread Local Storage (TLS) allocation as described in https://forum.opencv.org/t/memory-leak-detected-by-valgrind-in-cv-resize/3509:

    This looks like Thread Local Storage (TLS) allocation. This memory will be allocated once for each thread in the thread pool and will not be freed until program exits. It should not cause problems unless you create new threads many times (internal OpenCV thread pool does not do this).

    So this finding can be ignored unless the leak grows with e.g. each iteration of some loop. Try to repeat function call multiple times and check the size of the lost memory. If it grows - the leak is a problem.

    Further discussion on how to use OpenCV in a multi-threaded environment is provided here:

    How to properly Multithread in OpenCV in 2019?