0

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.

Edu MP
  • 3
  • 1
  • 4
    "_HERE THE MEMORY SHOULD HAVE BEEN FREED_": How do you know that it hasn't been? – user17732522 Mar 08 '23 at 03:26
  • can you describe the whole behaviour and why you think/know that the memory isn't given free? Do you run out of memory in your while(y<20) loop? Btw, in youe sample code you don't incement `y` – Micka Mar 08 '23 at 08:02
  • 2
    Run the program inside valgrind if you are running on Linux. That will give you a very good hint. – Something Something Mar 08 '23 at 08:31
  • I use top command in linux to monitore the memory usage – Edu MP Mar 08 '23 at 13:07
  • For some reason I hadn't run the program with Valgrind until now, I did it and the leak was reported as the accepted answer said. – Edu MP Mar 08 '23 at 14:32

1 Answers1

1

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?

  • This indeed seems very related to my problem – Edu MP Mar 08 '23 at 13:08
  • according to the link, TLS does not free the memory of the destroyed thread until exiting the progam. Is that true, even if memory consumption grows over and over? Is there a way to "manually" free the "unusable" (because the thread is already destroyed) TLS memory? – Micka Mar 08 '23 at 13:31