【OpenCV】有關記憶體釋放的一些問題
轉載請註明出處:http://blog.csdn.net/xiaowei_cqu/article/details/7586847
前一天把系統整個重寫了一遍,脈絡清晰了很多,也終於解決了以前很多崩潰,異常退出的問題。這裡小小總結一下自己遇到的麻煩。
1、記憶體洩露
記憶體洩露是說沒有釋放已經不能使用的記憶體,這裡一般指堆的記憶體才需要顯示的釋放。比如用malloc,calloc,realloc,new分配的記憶體是在堆上的,需要用free,delete顯示的回收。記憶體洩露最明顯的一是程式很慢,在執行程式時你可以啟動工作管理員,會看到程式佔用的記憶體一直“砰砰砰”的往上漲:
最後直接崩潰,或者你關閉程式的時候也會異常退出,出現
Debug Assertion Failed!
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
之類的問題。
除了new的物件我們知道要delete。OpenCV中使用cvCreateImage()新建一個IplImage*,以及使用cvCreateMat()新建一個CvMat*,都需要cvReleaseImage() cvReleaseMat()顯示的釋放
- IplImage* subImg=cvCreateImage( cvSize((img->width)*scale,(img->height)*scale), 8, 3 );
- CvMat *tempMat=cvCreateMat((img->width)*scale,(maxFace->height)*scale,CV_MAKETYPE(image->depth,image->nChannels));
- cvReleaseImage(&subImg);
- cvReleaseMat(&tempMat);
IplImage* subImg=cvCreateImage( cvSize((img->width)*scale,(img->height)*scale), 8, 3 );
CvMat *tempMat=cvCreateMat((img->width)*scale,(maxFace->height)*scale,CV_MAKETYPE(image->depth,image->nChannels));
cvReleaseImage(&subImg);
cvReleaseMat(&tempMat);
另外一些函式要用到 CvSeq*來存放結果(通常這些都要用cvCreateMemStorage()事先分配一塊記憶體CvMemStorage*),都要是釋放掉相應的記憶體,這是很難找的。
比如從二值影象中尋找輪廓的函式cvFindContours():
- CvMemStorage* m_storage=cvCreateMemStorage(0);
- CvSeq * m_contour=0;
- cvFindContours( img, m_storage, &m_contour, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
- //釋放記憶體
- cvReleaseMemStorage(&m_storage);
CvMemStorage* m_storage=cvCreateMemStorage(0);
CvSeq * m_contour=0;
cvFindContours( img, m_storage, &m_contour, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
//釋放記憶體
cvReleaseMemStorage(&m_storage);
以及人臉識別中檢測人臉的函式:
- CvMemStorage* m_storage=cvCreateMemStorage(0);
- CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );
- CvSeq* faces = cvHaarDetectObjects( img, cascade, m_storage,1.1, 2, 0,cvSize(30, 30) );
- //釋放記憶體
- cvReleaseMemStorage( &faces->storage);
- cvReleaseHaarClassifierCascade( &cascade );
CvMemStorage* m_storage=cvCreateMemStorage(0);
CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );
CvSeq* faces = cvHaarDetectObjects( img, cascade, m_storage,1.1, 2, 0,cvSize(30, 30) );
//釋放記憶體
cvReleaseMemStorage( &faces->storage);
cvReleaseHaarClassifierCascade( &cascade );
注意這裡我們可以使用
cvReleaseMemStorage( &faces->storage);
來釋放m_storate,也可以使用:
cvReleaseMemStorage(&m_storage);
釋放記憶體,這是等效的,但一定不要用兩次!!
2、一塊記憶體多次釋放
對應沒有釋放記憶體,對應就是一個記憶體釋放多次,如同上面的 cvReleaseMemStorage用了兩次。可能報錯的地方:
- __declspec(noinline)
- void __cdecl _CRT_DEBUGGER_HOOK(int _Reserved)
- {
- /* assign 0 to _debugger_hook_dummy so that the function is not folded in retail */
- (_Reserved);
- _debugger_hook_dummy = 0;
- }
__declspec(noinline)
void __cdecl _CRT_DEBUGGER_HOOK(int _Reserved)
{
/* assign 0 to _debugger_hook_dummy so that the function is not folded in retail */
(_Reserved);
_debugger_hook_dummy = 0;
}
或者: Unhandled exception at XXXXXXXXXX in XXX.exe: XXXXXXXXXXX: 堆已損壞。
除了上述的MemStorge問題,使用cvQueryFrame()取出CvCapture*每幀影象,只需在最後釋放CvCapture*,不需要釋放IplImage*
- CvCapture* pCapture = cvCreateCameraCapture(-1);
- IplImage* pFrame=cvQueryFrame( pCapture );
- cvReleaseCapture(&pCapture);
CvCapture* pCapture = cvCreateCameraCapture(-1);
IplImage* pFrame=cvQueryFrame( pCapture );
cvReleaseCapture(&pCapture);
*這篇是以前寫的,其實還是建議大家用C++介面的OpenCV,記憶體問題很少了~
相關文章
- vector clear() 方法 記憶體釋放問題記憶體
- Chrome 再次最佳化記憶體佔用問題,新增記憶體釋放開關Chrome記憶體
- C/C++記憶體釋放應注意的問題C++記憶體
- 請教一個java程式記憶體釋放的問題Java記憶體
- vector 的記憶體釋放記憶體
- 有關記憶體的思考題記憶體
- 記憶體的分配與釋放,記憶體洩漏記憶體
- Linux釋放記憶體及手動釋放Oracle共享記憶體段Linux記憶體Oracle
- XCode釋放記憶體XCode記憶體
- linux釋放記憶體Linux記憶體
- vector 避免記憶體頻繁分配釋放與手動釋放vector記憶體記憶體
- 正確釋放Vector的記憶體記憶體
- C 有關記憶體的小謎題記憶體
- iOS 解決設定rootViewController 記憶體不釋放問題iOSViewController記憶體
- 低版本IE瀏覽器iframe記憶體不釋放問題瀏覽器記憶體
- Java記憶體問題的一些見解Java記憶體
- 關於C++ delete 來釋放new分配的記憶體C++delete記憶體
- 轉 linux 記憶體釋放Linux記憶體
- Linux釋放cache記憶體Linux記憶體
- linux 記憶體釋放命令Linux記憶體
- 關於java吃記憶體的問題Java記憶體
- golang 釋放記憶體機制的探索Golang記憶體
- MediaPlayer原始碼存在的記憶體洩漏問題,釋放資源的正確方式原始碼記憶體
- C# 垃圾回收釋放記憶體C#記憶體
- FireFox記憶體自動釋放Firefox記憶體
- Java記憶體模型FAQ(五)舊的記憶體模型有什麼問題?Java記憶體模型
- 關於PHP記憶體洩漏的問題PHP記憶體
- 如何主動釋放 HeapIdle 的記憶體API記憶體
- .Net記憶體管理釋放的兩種方式記憶體
- project中的堆疊記憶體,記憶體地址引用,gc相關問題Project記憶體GC
- 又是訊號量和共享記憶體沒有釋放的db待機記憶體
- 利用ipcrm清除資料庫crash後沒有釋放的記憶體段資料庫記憶體
- C/C++記憶體分配以及釋放C++記憶體
- Linux之 手動釋放記憶體Linux記憶體
- mongodb釋放記憶體-切換日誌MongoDB記憶體
- Linux下如何釋放cache記憶體Linux記憶體
- Linux系統釋放cache記憶體Linux記憶體
- 關於SQL Server的記憶體佔用問題SQLServer記憶體