简体   繁体   中英

Memory leak converting cv::Mat

I have seen this question asked before, but I have a similar issue with memory leaks, without using any dynamic memory allocation. This is a call to cv::Mat::convertTo which is used to convert a floating point Mat to a CV_8U mat (mType is 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);
}

The ImageFeatures::getDescriptors method is implemented as follows:

class ImageFeatures {
public:

    cv::Mat &getDescriptors(){
        return mDescriptors;
    }

private:

    cv::Mat mDescriptors;
};

However when running valgrind on this, I get the following report:

==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

This is interrupted mid-way or it ends up freezing my laptop.

So my question is: am I doing anything wrong?

Thanks!

I found the problem and it's strictly related to other parts of the application that aren't visible here. The DescriptorDataConverterPipelineLevel is a thread that was reading ImageFeatures objects from a RepeaterPipelineLevel that was cloning a stored object and offering it to the Converter every time it needed it:

FileReader -> Repeater -> Converter \
                                     Matcher -> Writer
Folder Reader ---------->  Converter/

However, since the queue between the converter and matcher was built with a linked list of unlimited capacity, without any feedback, the converter kept reading from the repeater and placing the data in the queue, even when the matcher finished processing.

The solution was to swap around the repeater and converter:

FileReader -> Converter -> Repeater \
                                     Matcher -> Writer
Folder Reader ---------->  Converter/ 

And now everything works fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM