2011-12-21 12 views
5

Tengo una pérdida de memoria en mi aplicación OpenCV. Es una aplicación de tamaño medio con una docena de clases y unas pocas miles de líneas de código. De alguna manera, me las arreglé para producir una gran pérdida de memoria en mi aplicación que se come toda mi memoria de 8 GB en pocos minutos. Estoy usando OpenCV C++ 2.3 en Ubuntu 11.10 con CMake.En una aplicación OpenCV, ¿cómo identifico la fuente de fuga de memoria y la arreglo?

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

Es una aplicación de seguimiento de la mano y procesar dos de vídeo simultaneamente a una velocidad de alrededor de 15 fps para cada cámara.

Intenté usar valgrind como a continuación, pero la salida de valgrind es tan grande que excede la cantidad de texto que el shell puede mantener en el búfer. Sé que puedo guardar el resultado en un archivo de registro, pero esperaba evitar la abrumadora tarea de leerlo todo. Este es el comando valgrind utilicé:

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

aquí es las últimas líneas de salida 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) 

¿Cuáles son algunas maneras mejores que puedo abordar el problema? ¿Hay algunas herramientas que puedan mostrarme de forma concisa qué llamadas a funciones están causando la mayoría de las asignaciones de memoria? Si valgrind es la respuesta, agradecería algunos consejos sobre cómo usarlo de una manera más eficiente ya que soy totalmente nuevo en esta herramienta.

+0

Si tuviera que adivinar, diría que probablemente esté asignando memoria a 'CameraPGR :: grabImage()' y nunca la libere. –

+0

He examinado esa función varias veces, no puedo encontrar el problema allí. Haré un poco más de tiempo con eso mañana. ¿Tiene alguna sugerencia sobre cómo puedo mejorar el proceso de encontrar la causa raíz de una pérdida de memoria? – Aras

+1

Sin ver ninguno de sus códigos, es realmente imposible adivinar lo que está pasando mal. ¿Liberas la memoria asignada en la pila de llamadas anterior? Si no, ahí está tu problema. –

Respuesta

5

No es una respuesta, sino una sugerencia: pasar de la interfaz C de OpenCV a C++. Si se usa adecuadamente, reducirá al mínimo las posibilidades de una fuga, ahora y en el futuro. Sus punteros inteligentes incrustados en los objetos automáticamente liberan memoria.

En el peor de los casos, tendrá una penalización de rendimiento (demasiados allocs/deallocs), pero esos son fáciles de detectar en un generador de perfiles.

interfaz El C++ está utilizando

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

Y usted no tiene que declarar punteros a las imágenes:

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(); 

Si usted tiene algún código heredado, o un tercero que utiliza la otra interfaz, que es fácil de convertir de ida y vuelta:

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

Otros tipos de datos (como CvPoint) se convierten automáticamente. CvSeq se reemplaza por std::vector<T>

+0

Gracias por la sugerencia.Excepto por la parte en la que leí la imagen de la cámara que escribí hace un año, no uso la interfaz C en ningún otro lado. Desde que descubrí la interfaz C++ he estado usando eso constantemente. ¡Pero gracias de cualquier manera! – Aras

Cuestiones relacionadas