首頁 » Halcon » [C#/Halcon] 如何正確釋放記憶體? 有個實用的方法架構

[C#/Halcon] 如何正確釋放記憶體? 有個實用的方法架構

作者:

分類:

前言

Halcon 要與 C# 整合時,會需要避免記憶體洩漏的問題,尤其是影像一張動輒20MB或是每秒取像120、240張的狀況,如果影像沒有被正確的釋放,記憶體就算再多,不用幾分鐘就會跳記憶體不足的警告。

Halcon Logo
Halcon Logo

我很喜歡用 C# 開發,好上手開發時程快之外,.NET強大的 GC(Garbage Collection)在記憶體管理上幾乎不用在意物件的釋放,反正用完GC會判斷物件的狀況來決定要保留或是扔掉。所以第一次用 Halcon 開發專案時,就碰上很多問題。

說明

簡單介紹,Halcon有自己的底層去管理記憶體,然後再包了個殼(Dll)給其他語言使用(C++, C#, Python, etc.),所以在使用上會需要去呼叫 HObject.Dispose()來釋放物件。

可以在網路上搜尋 Halcon programmers guide(連結),裡面會有很詳細的講解Halcon如何整合開發。文件中可以看到 Halcon 用了很多的篇幅在提醒開發人員記憶體管理(Memory Management)的資訊。

其中的11.1.3 From Declaration to Finalization 章節中有個段落提到:

  • Please note that HALCON operators always create a new object instance for output parameters and return values (but not in the“constructor-like”operator calls that modify the calling instance).
  • If the variable was already initialized, its old content (and the memory allocated for it) still exists until the garbage collector removes it.
  • If you want to remove it manually, you must call Dispose before assigning an object to it.

也就是除了物件在結尾需要釋放之外,在被賦值之前也需要呼叫Dispose來確保記憶體沒有洩漏。 

實際應用

說了這麼多,其實Halcon在開發靜態方法上有個容易理解的架構。用Halcon產生的.cs檔也是這架構哦。

static void MyMethod(HObject src, out HObject dst)
{
	//先宣告方法內會需要用到的Hobject,
	//並在使用前先呼叫Dispose
	//在結尾呼叫Dispose
	HOperatorSet.GenEmptyObj(out dst);
	HOperatorSet.GenEmptyObj(out HObject hMirror);
	
	try 
	{
		hMirror.Dispose(); //out前先Dispose
		HOperatorSet.MirrorImage(src, out hMirror, "row");
		dst.Dispose(); //out前先Dispose
		HOperatorSet.RotateImage(hMirror, out dst, 270, "constant");
	}
	catch (Exception ex)
	{
		//DoSomething...
	}
	finally
	{
		/*確保方法內的物件在各種狀態下(包含異常處理)都會被釋放*/
		hMirror.Dispose();
	}
}

結論

總結以下幾點,可以避開許多Halcon開發上的地雷:

  1. 在開頭宣告全部變數,在檢查也比較方便
  2. 用try…catch…finally
  3. 在每個out前先Dispose
  4. 在finally內釋放,確保在各種狀態下(包含異常處理)不會洩漏

另外也有非靜態的寫法,就等下次在介紹了

參考資料

「cian」的個人頭像

留言

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *