В приложении OpenCV как определить источник утечки памяти и устранить ее? - PullRequest
5 голосов
/ 21 декабря 2011

У меня утечка памяти в приложении OpenCV.Это приложение среднего размера с множеством классов и несколькими тысячами строк кода.Каким-то образом мне удалось вызвать большую утечку памяти в моем приложении, которая за несколько минут пожирает всю мою 8-гигабайтную память.Я использую OpenCV C ++ 2.3 в Ubuntu 11.10 с CMake.

An snapshot of how much memory is freed right after I terminate the app. I can watch the used memory go up to 4gig in a matter of a few minutes

Это приложение для отслеживания рук, которое обрабатывает два видеопотока одновременно с частотой кадров около 15 кадров в секунду для каждой камеры..

Я попытался использовать valgrind, как показано ниже, но вывод valgrind настолько велик, что превышает объем текстовой оболочки, который может храниться в буфере.Я знаю, что могу сохранить выходные данные в файл журнала, но я надеялся избежать сложной задачи по чтению всего этого.Вот команда valgrind, которую я использовал:

valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./Gibbon 

Вот несколько последних строк вывода valgrind:

==3573== 5,415,576 (1,176 direct, 5,414,400 indirect) bytes in 7 blocks are definitely lost in loss record 2,571 of 2,571
==3573==    at 0x4C28F9F: malloc (vg_replace_malloc.c:236)
==3573==    by 0x5B2ACD0: cv::fastMalloc(unsigned long) (in /usr/local/lib/libopencv_core.so.2.3.1)
==3573==    by 0x5A7FA9D: cvCreateImageHeader (in /usr/local/lib/libopencv_core.so.2.3.1)
==3573==    by 0x484538: CameraPGR::convertImageToOpenCV(FlyCapture2::Image*) (CameraPGR.cpp:212)
==3573==    by 0x483F52: CameraPGR::grabImage() (CameraPGR.cpp:134)
==3573==    by 0x473F86: start() (GibbonMain.cpp:368)
==3573==    by 0x4725CC: main (GibbonMain.cpp:108)
==3573== 
==3573== LEAK SUMMARY:
==3573==    definitely lost: 24,432 bytes in 33 blocks
==3573==    indirectly lost: 5,414,640 bytes in 15 blocks
==3573==      possibly lost: 2,314,837 bytes in 1,148 blocks
==3573==    still reachable: 496,811 bytes in 4,037 blocks
==3573==         suppressed: 0 bytes in 0 blocks
==3573== 
==3573== For counts of detected and suppressed errors, rerun with: -v
==3573== Use --track-origins=yes to see where uninitialised values come from
==3573== ERROR SUMMARY: 336 errors from 318 contexts (suppressed: 10 from 8)

Какими лучшими способами можно решить эту проблему?Существуют ли какие-либо инструменты, которые могут кратко показать мне, какие вызовы функций вызывают большую часть распределения памяти?Если ответом является valgrind, я был бы признателен за некоторые советы о том, как использовать его более эффективно, поскольку я совершенно новичок в этом инструменте.

1 Ответ

5 голосов
/ 21 декабря 2011

Не ответ, а предложение: перейти с интерфейса OpenCV C на C ++. При правильном использовании это сведет к минимуму ваши шансы на утечку, сейчас и в будущем. Его умные указатели, встроенные в объекты, автоматически освобождают память.

В худшем случае у вас будет штраф за производительность (слишком много ресурсов), но это легко заметить в профилировщике.

Интерфейс C ++ использует

Mat intead of IplImage, 
Point instead of CvPoint, 
cv::function() instead of cvFunction. 

И вам не нужно объявлять указатели на изображения:

Mat src = imread("myfile.jpg");
Mat gray; // note that I do not allocate it. 
// This is done automatically in the next functions
cv::cvtColor(src, gray, CV_BGR2GRAY);
imshow("Gray image", gray);
waitKey();

Если у вас есть какой-либо устаревший код или сторонний разработчик, который использует другой интерфейс, его легко преобразовать туда и обратно:

Mat src(width, height, CV_8UC3);
IplImage* legacyImg;
legacyImg = &(IplImage)src;

Другие типы данных (например, CvPoint) конвертируются автоматически. CvSeq заменяется на std::vector<T>

...