java opencv bytearray转mat_OpenCV开发中的内存管理问题
點(diǎn)擊上方藍(lán)字關(guān)注我們
微信公眾號(hào):OpenCV學(xué)堂
關(guān)注獲取更多計(jì)算機(jī)視覺(jué)與深度學(xué)習(xí)知識(shí)
引子
2020年第二篇技術(shù)文章,最近比較忙,事情比較多,搞了一個(gè)新的系列技術(shù)文章,還沒(méi)有完整的搞好,抽空寫一篇最近別人問(wèn)我的事情!
概述
如果你是OpenCV框架做開(kāi)發(fā)、特別是用OpenCV C++版本或者Java/Android版本JNI的調(diào)用的化,可能很多時(shí)候你遇到最棘手的問(wèn)題就是程序運(yùn)行會(huì)越來(lái)越慢,甚至死機(jī)了,原因很簡(jiǎn)單,有時(shí)候你有內(nèi)存泄漏問(wèn)題。做好下面幾件事情會(huì)幫助你在開(kāi)發(fā)中經(jīng)可能的避免OpenCV對(duì)象內(nèi)存泄漏陷阱。
記得調(diào)用release
OpenCV中很多數(shù)據(jù)結(jié)構(gòu)與對(duì)象都有一個(gè)release方法,記得用完這些對(duì)象跟數(shù)據(jù)容器之后調(diào)用release/destory方法。最典型的就是Mat對(duì)象的release方法,調(diào)用release并不會(huì)重根本上保證立刻回收內(nèi)存,它只是讓對(duì)象的引用計(jì)數(shù)減一,只有當(dāng)對(duì)象的引用計(jì)數(shù)為0的時(shí)候,才會(huì)回收內(nèi)存。此外release方法還是一個(gè)原子操作,也可以線程中被調(diào)用。這些方法對(duì)象列表如下:
Mat的release方法,表示釋放圖像內(nèi)存
FileStorage的releaseAndGetString方法,表示關(guān)閉文件,釋放所有內(nèi)存
Mat繼承類/封裝類,UMat、SparseMat等都調(diào)用release方法
VideoCapture/VideoWriter方法,調(diào)用release釋放緩沖區(qū)與資源
CUDA相關(guān)的調(diào)用releaseMemory方法,比如SURF_CUDA
rgbd相關(guān)的調(diào)用releasePyramids方法
使用allocate分配內(nèi)存的必須調(diào)用free()方法
對(duì)照一下,你平時(shí)有注意過(guò)這些不,沒(méi)有的話從現(xiàn)在開(kāi)始還來(lái)得及的!
濫用/重用變量導(dǎo)致內(nèi)存泄漏
注意要避免下面三種錯(cuò)誤代碼寫法
錯(cuò)誤一:
1Mat?m1;2for?(int?i?=?0;?i?100;?i++)?{
3?????????m1?=?Mat::zeros(Size(512,?512),?CV_8UC3);
4}
5imshow("input-m1",?m1);
6m1.release();
錯(cuò)誤方式:在循環(huán)中創(chuàng)建無(wú)數(shù)Mat對(duì)象,結(jié)果只釋放了一個(gè),很多人的循環(huán)就是這么寫的,妥妥的內(nèi)存泄漏!類似的代碼操作應(yīng)該避免。
錯(cuò)誤二:
1Mat?image?=?imread("D:/images/test.png");2image?=?getProcessed();
3imshow("input-image",?image);
錯(cuò)誤方式:以為可以少創(chuàng)建一個(gè)變量,結(jié)果是無(wú)法釋放內(nèi)存了,反復(fù)調(diào)用導(dǎo)致內(nèi)存泄漏,類似的代碼應(yīng)該避免。
錯(cuò)誤三:
有返回Mat對(duì)象,但是提前調(diào)用release釋放了,結(jié)果再次訪問(wèn)data數(shù)據(jù)塊,導(dǎo)致程序直接崩潰!需要特別注意!簡(jiǎn)單演示如下:
1#include?2#include?
3
4using?namespace?std;
5using?namespace?cv;
6Mat?my_process();
7int?main(int?argc,?char**?argv)?{
8????//?錯(cuò)誤三:
9????Mat?image?=?my_process();
10????imshow("input-image",?image);
11????waitKey(0);
12}
13Mat?my_process()?{
14?????Mat?m1?=?Mat::zeros(Size(512,?512),?CV_8UC3);
15?????//?TODO:?do?something?here
16?????m1.release();
17?????return?m1;
18}總結(jié)
使用C++開(kāi)發(fā),內(nèi)存跟指針問(wèn)題是很多開(kāi)發(fā)者頭疼的一件事情,OpenCV框架對(duì)內(nèi)存的管理已經(jīng)很智能化了,基本上代碼規(guī)范寫,記得release就不會(huì)有這個(gè)方面的問(wèn)題,但是還是小心為妙,特別是跨語(yǔ)言調(diào)用的時(shí)候比如Android/Java通過(guò)JNI調(diào)用OpenCV函數(shù),如果不注意release或者沒(méi)有正確release,很難找到原因!
最重要的一句話,記得release/free,歡迎留言分享你的觀點(diǎn)與想法!
?推薦閱讀?
?2019原創(chuàng)技術(shù)文章匯總
2018年原創(chuàng)技術(shù)文章匯總
OpenCV實(shí)戰(zhàn) | 噪聲生成與圖像加噪聲
OpenCV4系統(tǒng)化學(xué)習(xí)路線圖-視頻版本!
總結(jié)
以上是生活随笔為你收集整理的java opencv bytearray转mat_OpenCV开发中的内存管理问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python生成50个随机数_Pytho
- 下一篇: tcppwebbrower 关闭安全警报