OpenCV 4.7结合std::thread使用时出现内存泄漏问题求助
OpenCV 4.7线程环境下cv::Mat内存泄漏问题解决思路
问题描述
在myFunction函数中生成cv::Mat图像并填充至std::vector:
- 直接调用函数时,
vector生命周期结束后内存可正常释放; - 通过
std::thread执行函数时,若调用cv::cvtColor或cv::imwrite,vector销毁后内存无法释放。
当前使用OpenCV 4.7版本,已知3.2.0曾有类似线程相关问题但已修复。
复现代码
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); 取消注释此行,使用std::thread时会出现内存泄漏 myvector.push_back(oImage); x++; } /* 不执行cvtColor但取消注释以下4行,使用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(); // 直接调用函数无问题 std::cout << "out of scope"; // 此处内存应已释放 getchar(); } return 0; }
解决方案
强制释放vector内存
替换myvector.clear()为std::swap,强制销毁vector的内存,避免引用计数残留:std::vector<cv::Mat>().swap(myvector);或者手动遍历释放每个Mat的内部缓冲区:
for(auto& mat : myvector) { mat.release(); } myvector.clear();控制OpenCV内部线程
OpenCV的并行处理模块(如TBB/OpenMP)可能在子线程中残留资源,可在子线程中禁用内部并行:void myFunction(){ cv::setNumThreads(0); // 禁用OpenCV内部线程池 // 原有代码... std::vector<cv::Mat>().swap(myvector); cv::setNumThreads(cv::getNumberOfCPUs()); // 可选:恢复默认线程数 }手动管理Mat内存
避免使用默认的引用计数分配,手动创建独立内存的Mat:while(x < 1000){ uchar* buffer = new uchar[1000 * 2000 * 3]; cv::Mat oImage(1000, 2000, CV_8UC3, buffer); oImage.setTo(cv::Scalar(255,0,255)); // 使用clone()存入vector,确保每个Mat拥有独立内存 myvector.push_back(oImage.clone()); delete[] buffer; // 释放原始缓冲区 x++; }版本验证
尝试升级OpenCV至最新稳定版(如4.8+),或降级至4.5.x等经过广泛验证的版本,排查是否为版本回归问题。
内容的提问来源于stack exchange,提问作者Edu MP
相关产品推荐
相关产品推荐

