Memory leak on Mat creation
Valgrind is telling me the following:
==8885== 458,704 bytes in 1 blocks are definitely lost in loss record 17,981 of 18,027
==8885== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8885== by 0x33C0BA90: cv::fastMalloc(unsigned long) (in /usr/local/lib/libopencv_core.so.2.4.5)
==8885== by 0x33C51BF1: cv::Mat::create(int, int const*, int) (in /usr/local/lib/libopencv_core.so.2.4.5)
==8885== by 0x4196CD: cv::Mat::Mat(int, int, int, cv::Scalar_<double> const&) (mat.hpp:353)
==8885== by 0x41BEA6: clustering::mergeImages(cv::Mat, cv::Mat, std::string, std::string, float, float) (clustering.cpp:128)
==8885== by 0x41C582: clustering::mergePerceps(percepUnit, percepUnit, std::string) (clustering.cpp:205)
==8885== by 0x41D6E5: clustering::cluster(std::list<percepUnit, std::allocator<percepUnit> >&, std::list<percepUnit, std::allocator<percepUnit> >&, std::string) (clustering.cpp:428)
==8885== by 0x41FA45: segmentationClusteringThread::tick() (segmentationClusteringThread.cpp:351)
==8885== by 0x41FF41: segmentationClusteringThread::threadedFunction() (segmentationClusteringThread.cpp:425)
==8885== by 0x501AD2: ofThread::run() (in /home/bbogart/Projects/svn/Dreaming-Machine-3/trunk/DM/bin/DM)
==8885== by 0x578E52: Poco::ThreadImpl::runnableEntry(void*) (in /home/bbogart/Projects/svn/Dreaming-Machine-3/trunk/DM/bin/DM)
==8885== by 0x34E6BE99: start_thread (pthread_create.c:308)
Following is the mergeImages function:
Mat clustering::mergeImages(Mat scratch, Mat unit, const string maskOrImage, const string FGBG, const float scratchWeight, const float unitWeight) {
int width, height, type;
Mat merged, scratchImagePad, unitImagePad, scratchImage, unitImage;
Mat *smallImage, *bigImage;
// use the resolution and aspect of the largest of the pair.
if (unit.cols > scratch.cols)
width = unit.cols;
else
width = scratch.cols;
if (unit.rows > scratch.rows)
height = unit.rows;
else
height = scratch.rows;
if (maskOrImage == "mask")
type = CV_8UC1; // single channel mask
else if (maskOrImage == "image")
type = CV_8UC3; // three channel image
else
cout << "maskOrImage is not 'mask' or 'image'\n";
merged = Mat(height, width, type, Scalar::all(0));
scratchImagePad = Mat(height, width, type, Scalar::all(0));
unitImagePad = Mat(height, width, type, Scalar::all(0));
// weight images before summation.
scratchImage *= scratchWeight;
unitImage *= unitWeight;
// copy images into padded images.
scratch.copyTo(scratchImagePad(Rect((scratchImagePad.cols-scratchImage.cols)/2,
(scratchImagePad.rows-scratchImage.rows)/2,
scratchImage.cols,
scratchImage.rows)));
unit.copyTo(unitImagePad(Rect((unitImagePad.cols-unitImage.cols)/2,
(unitImagePad.rows-unitImage.rows)/2,
unitImage.cols,
unitImage.rows)));
merged = scratchImagePad+unitImagePad;
// blur mask on background objects
if (maskOrImage == "mask" and FGBG == "BG") {
gpu::GpuMat gInputImage, gOutputImage;
gInputImage.upload(merged);
gpu::blur(gInputImage, gOutputImage, Size(5,5)); // WAS Size(height*.15,width*.15); // blur with kernel to blow up to full size.
gOutputImage.download(merged);
gInputImage.release();
gOutputImage.release();
}
return(merged);
}
I've already posted a general question about memory leaks at Mats here (http://answers.opencv.org/question/14798/what-is-the-best-practise-for-passing-cvmats/), but I wanted to concentrate on this specific code, since its the greatest "definite" leak according to valgrind.
Thank you.
Well, if you're sure that this is a "definite" leak, it is better to report a bug at the code.opencv.org. And even better to work on a solution (in a form of pull request), since you already have all the environment ready for debug...
Valgrind builder is not added to the continuous integration system, but it should be added at some point. So, OpenCV may easily have a number of leaks... Thanks for the investigation!
Thanks @Kirill Kornyakov. I'm sure there is a leak in the sense that I can see the amount of ram increasing and the eventual crash of the program. I'm not sure the leak is where valgrind says it is, but where else to start? All the leaks I've seen valgrind report in this program seem to result from cv::Mat::create(), so I'll just try a simple program that does nothing but create a bunch of Mats and see if it leaks, and then report that as a bug.
Putting this same code above in a separate program does not lead to a leak, memory usage is stable.