std::vector及boost::container::vector未释放GPU内存的解决咨询
解决vector存储含cv::Mat结构体的内存释放问题
核心问题分析
std::vector::erase仅销毁目标元素(结构体),但结构体中的cv::Mat是否释放内存取决于其引用计数和内存类型:如果是GPU内存(如绑定cuda内存的cv::Mat或cv::cuda::GpuMat),若引用计数未归零或未手动触发释放,GPU显存不会自动回收。shrink_to_fit是标准库的请求式操作,编译器不一定会强制释放vector的冗余堆内存;boost容器同理。
具体解决方案
1. 强制释放cv::Mat的内存(关键)
在erase元素前,先手动清空结构体中的cv::Mat,强制释放其占用的GPU/CPU内存:
// 假设你的结构体定义为 struct MyData { cv::Mat img; }; // 遍历到要删除的迭代器iter时执行: iter->img.release(); // 强制释放Mat内存,无视引用计数 vec.erase(iter);
如果使用的是cv::cuda::GpuMat,同样调用release()即可释放GPU显存。
2. 彻底释放vector的冗余堆内存
用swap技巧强制回收vector的多余容量,这是C++标准中保证生效的方式:
- 若要清空所有元素:
std::vector<MyData>().swap(vec);
临时vector销毁时会释放全部内存,swap后vec的容量变为0。
- 若需保留部分元素:
std::vector<MyData> temp_vec; // 筛选需要保留的元素存入临时vector temp_vec.reserve(需保留的元素数量); for (const auto& data : vec) { if (符合保留条件) { temp_vec.push_back(data); } } // 交换后vec的容量匹配实际元素数量,冗余内存被释放 vec.swap(temp_vec);
3. 排查隐性引用
检查代码中是否有其他地方持有这些cv::Mat的引用(比如全局变量、其他容器、未销毁的函数返回值),若存在外部引用,即使vector元素被删除,内存也无法释放。
内容的提问来源于stack exchange,提问作者BarzanHayati
相关产品推荐
相关产品推荐

