天天看點

java opencv bytearray轉mat_OpenCV開發中的記憶體管理問題

java opencv bytearray轉mat_OpenCV開發中的記憶體管理問題

點選上方藍字關注我們

微信公衆号:OpenCV學堂

關注擷取更多計算機視覺與深度學習知識

引子

2020年第二篇技術文章,最近比較忙,事情比較多,搞了一個新的系列技術文章,還沒有完整的搞好,抽空寫一篇最近别人問我的事情!

概述

如果你是OpenCV架構做開發、特别是用OpenCV C++版本或者Java/Android版本JNI的調用的化,可能很多時候你遇到最棘手的問題就是程式運作會越來越慢,甚至當機了,原因很簡單,有時候你有記憶體洩漏問題。做好下面幾件事情會幫助你在開發中經可能的避免OpenCV對象記憶體洩漏陷阱。

記得調用release

OpenCV中很多資料結構與對象都有一個release方法,記得用完這些對象跟資料容器之後調用release/destory方法。最典型的就是Mat對象的release方法,調用release并不會重根本上保證立刻回收記憶體,它隻是讓對象的引用計數減一,隻有當對象的引用計數為0的時候,才會回收記憶體。此外release方法還是一個原子操作,也可以線程中被調用。這些方法對象清單如下:

  • Mat的release方法,表示釋放圖像記憶體
  • FileStorage的releaseAndGetString方法,表示關閉檔案,釋放所有記憶體
  • Mat繼承類/封裝類,UMat、SparseMat等都調用release方法
  • VideoCapture/VideoWriter方法,調用release釋放緩沖區與資源
  • CUDA相關的調用releaseMemory方法,比如SURF_CUDA
  • rgbd相關的調用releasePyramids方法
  • 使用allocate配置設定記憶體的必須調用free()方法

對照一下,你平時有注意過這些不,沒有的話從現在開始還來得及的!

濫用/重用變量導緻記憶體洩漏

注意要避免下面三種錯誤代碼寫法

錯誤一:

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

錯誤方式:在循環中建立無數Mat對象,結果隻釋放了一個,很多人的循環就是這麼寫的,妥妥的記憶體洩漏!類似的代碼操作應該避免。

錯誤二:

1Mat image = imread("D:/images/test.png");
2image = getProcessed();
3imshow("input-image", image);
           

錯誤方式:以為可以少建立一個變量,結果是無法釋放記憶體了,反複調用導緻記憶體洩漏,類似的代碼應該避免。

錯誤三:

有傳回Mat對象,但是提前調用release釋放了,結果再次通路data資料塊,導緻程式直接崩潰!需要特别注意!簡單示範如下:

1#include 
 2#include 
 3
 4using namespace std;
 5using namespace cv;
 6Mat my_process();
 7int main(int argc, char** argv) {
 8    // 錯誤三:
 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}
           

總結

使用C++開發,記憶體跟指針問題是很多開發者頭疼的一件事情,OpenCV架構對記憶體的管理已經很智能化了,基本上代碼規範寫,記得release就不會有這個方面的問題,但是還是小心為妙,特别是跨語言調用的時候比如Android/Java通過JNI調用OpenCV函數,如果不注意release或者沒有正确release,很難找到原因!

最重要的一句話,記得release/free,歡迎留言分享你的觀點與想法!

 推薦閱讀 

 2019原創技術文章彙總

2018年原創技術文章彙總

OpenCV實戰 | 噪聲生成與圖像加噪聲

OpenCV4系統化學習路線圖-視訊版本!

java opencv bytearray轉mat_OpenCV開發中的記憶體管理問題

繼續閱讀