我有一段相当简单的代码,我在函数(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和线程有问题,但现在应该可以修复。
1条答案
按热度按时间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?