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

我很喜歡用 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開發上的地雷:
- 在開頭宣告全部變數,在檢查也比較方便
- 用try…catch…finally
- 在每個out前先Dispose
- 在finally內釋放,確保在各種狀態下(包含異常處理)不會洩漏
另外也有非靜態的寫法,就等下次在介紹了
發佈留言