OpenCV和std:thread的内存泄漏

egdjgwm8  于 2023-03-09  发布在  其他
关注(0)|答案(1)|浏览(301)

我有一段相当简单的代码,我在函数(myFunction)中生成一些cv::Mat图像,并用它们填充std::vector,当向量被填充时,内存使用量增加,当向量超出作用域后,它使用的内存按预期释放。
但是由于某种原因,如果我在向向量添加Mat之前执行cv::cvtColor,那么当向量超出作用域之后,内存不会被释放;同样,如果我在向量超出作用域之前迭代向量并执行cv::imwrite函数,那么内存也不会被释放。
这两个问题只会在我在std::head中执行myFunction时发生,如果我不使用std:thread,根本不会发生内存泄漏。
这是我的代码:

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;
}

我使用的是OpenCV 4.7,我认为在使用3.2.0版本时opencv和线程有问题,但现在应该可以修复。

5f0d552i

5f0d552i1#

我已经使用valgrind制作了一个可重复性最小的示例,您观察到的内存泄漏很可能与https://forum.opencv.org/t/memory-leak-detected-by-valgrind-in-cv-resize/3509中描述的 * 线程本地存储(TLS)分配 * 有关:
这看起来像线程本地存储(TLS)分配。这个内存将为线程池中的每个线程分配一次,并且直到程序退出才会释放。除非您多次创建新线程,否则它不会导致问题(内部OpenCV线程池不会这样做)。
因此,除非泄漏随着某个循环的每次迭代而增长,否则可以忽略此发现。尝试多次重复函数调用并检查丢失内存的大小。如果泄漏增长,则泄漏是一个问题。
此处提供了有关如何在多线程环境中使用OpenCV的进一步讨论:
How to properly Multithread in OpenCV in 2019?

相关问题