内存泄漏转换 cv::Mat
Memory leak converting cv::Mat
我之前看过 this 问题,但我有一个类似的内存泄漏问题,没有使用任何动态内存分配。这是对 cv::Mat::convertTo 的调用,用于将浮点 Mat 转换为 CV_8U mat(mType 为 0):
void DescriptorDataConverterPipelineLevel::process() {
Queue<void *> *inputQueue = mInputQueues.at(0);
ImageFeatures *imageFeatures = (ImageFeatures *) inputQueue->pop();
convertMatrix(imageFeatures->getDescriptors());
mOutputQueue->push(imageFeatures);
}
void DescriptorDataConverterPipelineLevel::convertMatrix(cv::Mat &matrix) {
matrix.convertTo(matrix, mType);
}
ImageFeatures::getDescriptors方法实现如下:
class ImageFeatures {
public:
cv::Mat &getDescriptors(){
return mDescriptors;
}
private:
cv::Mat mDescriptors;
};
然而,当 运行 valgrind 对此时,我得到以下报告:
==9616== 1,240,114,808 bytes in 24,210 blocks are possibly lost in loss record 581 of 581
==9616== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9616== by 0x4F5ED87: cv::fastMalloc(unsigned long) (in /usr/lib/x86_64-linux-gnu/libopencv_core.so.2.4.8)
==9616== by 0x4EB94AA: cv::Mat::create(int, int const*, int) (in /usr/lib/x86_64-linux-gnu/libopencv_core.so.2.4.8)
==9616== by 0x4EC0A69: cv::_OutputArray::create(cv::Size_<int>, int, int, bool, int) const (in /usr/lib/x86_64-linux-gnu/libopencv_core.so.2.4.8)
==9616== by 0x4FD7BE3: cv::Mat::convertTo(cv::_OutputArray const&, int, double, double) const (in /usr/lib/x86_64-linux-gnu/libopencv_core.so.2.4.8)
==9616== by 0x418640: DescriptorDataConverterPipelineLevel::process() (DescriptorDataConverterPipelineLevel.cpp:33)
==9616== by 0x406B28: PipelineLevel::run() (PipelineLevel.hpp:75)
==9616== by 0x419729: Thread::execute() (Thread.cpp:39)
==9616== by 0x5ECCA3F: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==9616== by 0x6B2A181: start_thread (pthread_create.c:312)
==9616== by 0x663E47C: clone (clone.S:111)
==9616==
==9616== LEAK SUMMARY:
==9616== definitely lost: 0 bytes in 0 blocks
==9616== indirectly lost: 0 bytes in 0 blocks
==9616== possibly lost: 1,240,347,280 bytes in 24,478 blocks
==9616== still reachable: 4,198,805 bytes in 49,931 blocks
==9616== suppressed: 0 bytes in 0 blocks
==9616== Reachable blocks (those to which a pointer was found) are not shown.
==9616== To see them, rerun with: --leak-check=full --show-leak-kinds=all
这在中途中断,或者最终导致我的笔记本电脑死机。
所以我的问题是:我做错了什么吗?
谢谢!
我发现了问题,它与此处不可见的应用程序的其他部分密切相关。 DescriptorDataConverterPipelineLevel 是一个从 RepeaterPipelineLevel 读取 ImageFeatures 对象的线程,该线程正在克隆存储的对象并在每次需要时将其提供给 Converter:
FileReader -> Repeater -> Converter \
Matcher -> Writer
Folder Reader ----------> Converter/
但是,由于转换器和匹配器之间的队列是用无限容量的链表构建的,没有任何反馈,即使匹配器完成处理,转换器也会继续从转发器读取数据并将数据放入队列中.
解决方案是交换中继器和转换器:
FileReader -> Converter -> Repeater \
Matcher -> Writer
Folder Reader ----------> Converter/
现在一切正常。
我之前看过 this 问题,但我有一个类似的内存泄漏问题,没有使用任何动态内存分配。这是对 cv::Mat::convertTo 的调用,用于将浮点 Mat 转换为 CV_8U mat(mType 为 0):
void DescriptorDataConverterPipelineLevel::process() {
Queue<void *> *inputQueue = mInputQueues.at(0);
ImageFeatures *imageFeatures = (ImageFeatures *) inputQueue->pop();
convertMatrix(imageFeatures->getDescriptors());
mOutputQueue->push(imageFeatures);
}
void DescriptorDataConverterPipelineLevel::convertMatrix(cv::Mat &matrix) {
matrix.convertTo(matrix, mType);
}
ImageFeatures::getDescriptors方法实现如下:
class ImageFeatures {
public:
cv::Mat &getDescriptors(){
return mDescriptors;
}
private:
cv::Mat mDescriptors;
};
然而,当 运行 valgrind 对此时,我得到以下报告:
==9616== 1,240,114,808 bytes in 24,210 blocks are possibly lost in loss record 581 of 581
==9616== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9616== by 0x4F5ED87: cv::fastMalloc(unsigned long) (in /usr/lib/x86_64-linux-gnu/libopencv_core.so.2.4.8)
==9616== by 0x4EB94AA: cv::Mat::create(int, int const*, int) (in /usr/lib/x86_64-linux-gnu/libopencv_core.so.2.4.8)
==9616== by 0x4EC0A69: cv::_OutputArray::create(cv::Size_<int>, int, int, bool, int) const (in /usr/lib/x86_64-linux-gnu/libopencv_core.so.2.4.8)
==9616== by 0x4FD7BE3: cv::Mat::convertTo(cv::_OutputArray const&, int, double, double) const (in /usr/lib/x86_64-linux-gnu/libopencv_core.so.2.4.8)
==9616== by 0x418640: DescriptorDataConverterPipelineLevel::process() (DescriptorDataConverterPipelineLevel.cpp:33)
==9616== by 0x406B28: PipelineLevel::run() (PipelineLevel.hpp:75)
==9616== by 0x419729: Thread::execute() (Thread.cpp:39)
==9616== by 0x5ECCA3F: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==9616== by 0x6B2A181: start_thread (pthread_create.c:312)
==9616== by 0x663E47C: clone (clone.S:111)
==9616==
==9616== LEAK SUMMARY:
==9616== definitely lost: 0 bytes in 0 blocks
==9616== indirectly lost: 0 bytes in 0 blocks
==9616== possibly lost: 1,240,347,280 bytes in 24,478 blocks
==9616== still reachable: 4,198,805 bytes in 49,931 blocks
==9616== suppressed: 0 bytes in 0 blocks
==9616== Reachable blocks (those to which a pointer was found) are not shown.
==9616== To see them, rerun with: --leak-check=full --show-leak-kinds=all
这在中途中断,或者最终导致我的笔记本电脑死机。
所以我的问题是:我做错了什么吗?
谢谢!
我发现了问题,它与此处不可见的应用程序的其他部分密切相关。 DescriptorDataConverterPipelineLevel 是一个从 RepeaterPipelineLevel 读取 ImageFeatures 对象的线程,该线程正在克隆存储的对象并在每次需要时将其提供给 Converter:
FileReader -> Repeater -> Converter \
Matcher -> Writer
Folder Reader ----------> Converter/
但是,由于转换器和匹配器之间的队列是用无限容量的链表构建的,没有任何反馈,即使匹配器完成处理,转换器也会继续从转发器读取数据并将数据放入队列中.
解决方案是交换中继器和转换器:
FileReader -> Converter -> Repeater \
Matcher -> Writer
Folder Reader ----------> Converter/
现在一切正常。