2011-12-21 2 views
5

OpenCV 응용 프로그램에서 메모리 누수가 발생했습니다. 수십 개의 클래스와 수천 줄의 코드가있는 중간 크기의 응용 프로그램입니다. 어쨌든, 나는 애플리케이션에서 많은 메모리 누수를 일으켜 몇 분 안에 8GB 메모리를 모두 없애 버렸다. 나는 OpenCV C++ 2.3을 Ubuntu 11.10에서 CMake와 함께 사용하고 있습니다.OpenCV 응용 프로그램에서 메모리 누수의 원인을 확인하고 수정하려면 어떻게합니까?

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

그것은 손 추적 애플리케이션이며 약 15fps의 각 카메라에 대해 두 개의 비디오 프레임 레이트로 simultaneusly 스트림을 처리한다.

아래처럼 valgrind를 사용해 보았지만 valgrind의 출력이 너무 커서 버퍼에 저장할 수있는 텍스트 셸의 양을 초과합니다. 출력을 로그 파일에 저장할 수 있다는 것을 알고 있지만, 모든 것을 통해 읽기의 어려운 작업을 피하기를 희망했습니다. 여기

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

는 Valgrind의 출력의 마지막 몇 줄입니다 : 여기 내가 사용하는 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가 답이라면, 나는이 도구를 완전히 처음 접했기 때문에보다 효과적인 방법으로 사용하는 방법에 대한 힌트를 얻을 수 있습니다.

+0

으로 바뀌 었습니다. 나는 당신이 아마도'CameraPGR :: grabImage()'의 주위에 어딘가에 메모리를 할당하고 결코 그것을 풀어 놓고 있다고 말할 것입니다. –

+0

나는 그 기능을 여러 번 보았지만 그곳에서 문제를 발견 할 수 없다. 나는 내일 그것으로 더 어지럽히는 약간을 할 것이다. 메모리 누출의 근본 원인을 찾는 과정을 개선 할 수있는 방법에 대한 제안이 있습니까? – Aras

+1

코드를 보지 않고 무엇이 잘못 될지 추측하는 것은 정말로 불가능합니다. 위의 호출 스택에 할당 된 메모리를 해제합니까? 그렇지 않다면 문제가 있습니다. –

답변

5

대답이 아니지만 제안 : OpenCV C 인터페이스에서 C++로 이동하십시오. 제대로 사용하면 현재와 미래의 누수 가능성을 최소화 할 수 있습니다. 객체에 임베드 된 스마트 포인터는 자동으로 메모리를 비 웁니다.

최악의 경우 성능이 저하 될 수 있습니다 (allocs/deallocs가 너무 많음). 그러나 프로파일 러에서 쉽게 찾을 수 있습니다. 일부 레거시 코드가있는 경우

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

를, 또는 다른을 사용하는 타사 : 이미지에 대한 포인터를 선언 할

는 C++ 인터페이스는

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

을 사용하고 있습니다 그리고 당신은이 없습니다 같은 (

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

다른 데이터 유형,243 : 인터페이스, 그것은 앞뒤로 전환하는 것은 쉽다)가 자동으로 변환됩니다. CvSeqstd::vector<T>

+0

제안 해 주셔서 감사합니다.1 년 전 제가 쓴 카메라의 이미지를 읽는 부분을 제외하고는 어디에서나 C 인터페이스를 사용하지 않습니다. C++ 인터페이스를 발견 한 이래로 나는 그것을 지속적으로 사용 해왔다. 어쨌든 고마워! – Aras

관련 문제