2011-12-21 15 views
5

OpenCV uygulamasında bir bellek sızıntısı var. Sınıfları bir dozon ve birkaç bin satır kod ile orta ölçekli bir uygulama. Bir şekilde, uygulamamda, 8gb belleğimin tümünü birkaç dakika içinde yediğimde büyük bir bellek sızıntısı üretmeyi başardım. CMake ile Ubuntu 11.10 üzerinde OpenCV C++ 2.3 kullanıyorum.Bir OpenCV uygulamasında, bellek sızıntısı kaynağını nasıl belirleyebilir ve çözebilirim?

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

Bir el izleme uygulamasıdır ve çevresinde her kamera için 15fps iki video bir kare hızında eş zamanlı olarak 'akarsu işlemek.

Aşağıdaki gibi valgrind kullanmayı denedim, ancak valgrind çıkışı, metin kabuğunun tamponda tutabildiği miktarı aşan çok büyüktür. Çıktının bir kütük dosyasına kaydedilebileceğini biliyorum, ama tüm bunları okumanın göz korkutucu görevinden kaçınmayı umuyordum. İşte

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

valgrind çıkışının son birkaç satır:: İşte kullanılan valgrind komuttur

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

bu sorunu yaklaşabilir bazı iyi yolları nelerdir? Bellek çağrılarının çoğuna hangi işlev çağrılarının neden yol açtığını kısaca gösterebilecek bazı araçlar var mı? Cevabın cevabı ise, bu araç için tamamen yeni olduğumdan, daha verimli bir şekilde nasıl kullanılacağına dair bazı ipuçlarını takdir ediyorum.

+0

ile değiştirilirse tahmin etmeliydim, muhtemelen CameraPGR :: grabImage() 'etrafında bir yere bellek ayırıyorsunuz ve asla boş bırakmıyorsunuz. –

+0

Bu işleve birkaç kez baktım, sorunu burada bulamıyorum. Yarın bununla biraz daha uğraşacağım. Bellek sızıntısının temel nedenini bulma sürecini nasıl geliştirebileceğime dair herhangi bir öneriniz var mı? – Aras

+1

Kodunuzun hiçbirini görmeden, neyin yanlış gittiğini tahmin etmek gerçekten imkansız. Yukarıdaki arama kutusuna tahsis edilen hafızayı boşaltıyor musunuz? Eğer değilse, senin problemin var. –

cevap

5

Bir yanıt değil, bir öneri: OpenCV C arabiriminden C++ 'ya geçin. Düzgün kullanılırsa, şimdi ve gelecekte bir sızıntı olasılığını en aza indirecektir. Nesneleri gömülü akıllı işaretçiler otomatik olarak boş hafıza.

En kötü durumda, bir performans cezası (çok fazla allocs/deallocs) olacaktır, ancak bunlar bir profilerde kolayca bulunabilir. Eğer bazı eski kodunuz varsa

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

veya başka kullanan bir üçüncü taraf: görüntülere işaretçileri ilan etmek

C++ arayüzü

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

kullanıyor Ve yok gibi (

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

Diğer veri türleri: arayüz, ileri geri dönüştürmek için kolay) otomatik olarak dönüştürülür. CvSeq, std::vector<T>

+0

Öneriniz için teşekkürler.Bir yıl kadar önce yazdığım fotoğraf makinesindeki görüntüyü okuduğum bölüm dışında, C arayüzünü başka bir yerde kullanmıyorum. C++ arayüzünü keşfettiğimden beri bunu sürekli kullanıyorum. Yinede teşekkürler! – Aras