2011-12-21 48 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

これは手追跡アプリケーションであり、それは2つのビデオの周り各カメラの15fpsのフレームレートでsimultaneuslyストリームを処理します。

私は以下のように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が答えであれば、私はこのツールを完全に新しくして以来、より効率的な方法で使用する方法についていくつかのヒントをいただきたいと思います。

+0

に置き換えられました。私が推測しなければならないのは、おそらく、あなたがおそらく 'CameraPGR :: grabImage()'のどこかにメモリを割り当てていて決して解放しないと言うでしょう。 –

+0

私はその機能を何度も見てきましたが、そこで問題を見つけることはできません。私は明日それをもうすぐ回します。メモリリークの根本的な原因を突き止めるプロセスをどのように改善できるかについてご意見はありますか? – Aras

+1

あなたのコードを見ることなく、間違っていることを推測することは本当に不可能です。上記の呼び出しスタックに割り当てられているメモリを解放しますか?そうでなければ、あなたの問題があります。 –

答えて

5

答えはありませんが、提案:OpenCV CインターフェイスからC++に移動します。適切に使用されると、現在および将来のリークの可能性が最小限に抑えられます。オブジェクトに埋め込まれたスマートポインタは自動的にメモリを解放します。

最悪の場合、パフォーマンスの低下(あまりにも多くのallocs/dealloc)がありますが、それらはプロファイラで見つけるのが簡単です。

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; 

その他のデータ型(など))が自動的に変換されます。 CvSeqstd::vector<T>

+0

提案していただきありがとうございます。私が1年前に書いたカメラからの画像を読んでいる部分を除いて、私はどこでもCのインターフェイスを使っていません。私はC++インターフェイスを発見して以来、私はそれを絶えず使用してきました。とにかくありがとう! – Aras

関連する問題