HALCON: 内存管理(Memory Management)
內存管理(Memory Management)
.net框架的運行時環境CLR(公共語言運行時)有一種被稱為垃圾收集器的機制,CLR使用它來從內存中移除不再需要的.net對象。
正如前面提到的,在導出的c#代碼中,每個標志性的對象都由一個.net HObject對象表示。從垃圾收集器的角度來看,.net HObject對象相當小。因此,它可能不會從內存中收集,盡管底層的iconic對象(例如圖像)實際上可能會占用很大一部分內存。為了避免這種影響導致的內存泄漏,在導出的代碼中,每個iconic對象在被賦值之前都會被顯式地清除(disposed)。
HALCON的所有類,不僅是HImage、HRegion、HTuple、HFramegrabber等,還有在過程方法中調用操作符時使用的類HObject,都會在析構函數中自動釋放已分配的資源(參見“析構函數和HALCON操作符”一節)。此外,當重新構造實例時,例如,通過“構造函數和Halcon操作符”一節中提到的一個已經初始化的實例調用CreateBarCodeModel,已經分配的內存在重用實例之前自動釋放。因此,在HALCON/c++中不需要調用操作符ClearObj; 更重要的是,如果您使用它,HALCON將會抱怨已經釋放的內存。要在實例超出范圍之前顯式地釋放資源,可以調用實例的Clear()方法。
HALCON提供了復雜的內存管理,不僅可以處理iconic對象,還可以分配/釋放任意數據。請專門使用相應的HALCON擴展包接口例程。不要使用操作系統的標準例程(如malloc和free)在堆上創建/銷毀內存塊,因為HALCON例程提供了緩存機制、臨時數據的垃圾收集和調試工具。
我們強烈建議不要在HALCON操作符中使用全局變量。如果它們不可避免,至少使它們在使用文件中是靜態的。如果這是不可取的,將它們分組到結構中,以保持全局名稱的數量較小。
如果使用靜態變量,請注意它們是在多個線程之間共享的。請注意,HALCON使用多線程來利用多處理器或多核硬件。這意味著,您的代碼的多個實例實際上將共享所有靜態變量!!!此外,要注意大型靜態數組會消耗大量內存—請記住,HALCON是一個包含數百個操作符的非常大的系統。
永久數據(Permanent Data)
HALCON擴展包接口還提供了永久分配/釋放內存的例程(參見圖3.4和圖3.5)。它們的工作方式類似于標準的C過程malloc和free,但對小數據塊使用緩存機制,并提供額外的調試信息。
Names
??? HAlloc, HRealloc, HFree, HNewImage, HNewImagePtr, HAllocXLDCont, HFreeXLDCont
Synopsis
??? #include "Halcon.h"
??? Herror HAlloc( Hproc_handle proc_handle, size_t?????? size, void???????? **pointer)
??? Herror HRealloc(Hproc_handle proc_handle, void ????????*pointer
?????????????????? size_t?????? size, void???????? **new_pointer)
??? Herror HFree( Hproc_handle? proc_handle, void????????? *pointer)
??? Herror HNewImage(Hproc_handle? proc_handle, Himage??????? *image,
????????????????????? HINT????????? kind, HIMGDIM?????? width, HIMGDIM?????? height)
??? Herror HNewImagePtr( Hproc_handle? proc_handle,
????????????????????????? Himage??????? *image, HINT????????? kind,
????????????????????????? HIMGDIM?????? width, HIMGDIM?????? height,
????? ????????????????????void????????? *data, HBOOL???????? initImg)
??? Herror HAllocXLDCont( Hproc_handle? proc_handle, Hcont **cont, HITEMCNT num_points)
??? Herror HFreeXLDCont( Hproc_handle? proc_handle, Hcont???????? *cont)
Figure 3.4: General memory management within HALCON.
注意,與HAllocLocal相比,HAlloc分配的內存在HALCON操作符執行后不會自動釋放。因此,應該使用這個例程來分配永久數據。
例如,存儲在HALCON iconic對象數據庫中的所有iconic對象都用這個例程分配(參見“處理標志性對象和控制參數”和“典型供應程序的特殊例程”一章)。
For example, all the iconic objects stored in the HALCON database of iconic objects are allocated with this routine (see chapter “Handling Iconic Objects and Control Parameters” and chapter “Special Routines for Typical Supply Procedures”).
HNewImage在數據結構Himage(參見“像素數據(Himage)”)中基于HAlloc分配原始圖像數據。此外,將初始化image并將時間戳設置為當前時間。如果使用HALCON操作符set_system將'init_new_image'設置為'true',則圖像矩陣本身初始化為0。該標志可以在HALCON內部使用擴展包接口調用HReadGV讀取。
HReadGV (proc_handle HGInitNewImage &init_new_img);
with init_new_img of type HBOOL and set:
HWriteGV (proc_handle HGInitNewImage,{真,假});
因此,可以緩沖該標志的全局設置,在HNewImage之前將該標志設置為FALSE,然后在之后恢復舊的值,如果你想在任何情況下防止初始化。
HNewImagePtr不為圖像數據分配內存,而是將指針數據插入到Himage結構圖像中。對于這個例程,圖像數據的初始化是通過參數initImg控制的。注意,如果你在底層的Himage結構中插入了一個沒有通過HAlloc分配的內存塊(參見“創建對象和寫入輸出對象參數”一節中的HPutImage),你會在釋放圖像對象時遇到程序崩潰。
對于HNewImage和HNewImagePtr,image中原始數據的像素類型由參數kind指定。支持的值請參見圖4.2。
HAllocXLDCont分配一個Hcont類型的XLD輪廓(參見“XLD (Hcont, Hpoly)”一節),包括num_points輪廓點的內存。在內部,這個例程是基于HAlloc的。HFreeXLDCont用于再次釋放輪廓線(包括所有為cont定義的點和所有屬性,參見此頁)。
Names
??? HAllocRL, HAllocRLNum, HReallocRLNum, HFreeRL
Synopsis
??? #include "Halcon.h"
??? Herror HAllocRL(Hproc_handle proc_handle, Hrlregion??? **region)
??? Herror HAllocRLNum(Hproc_handle proc_handle, Hrlregion??? **region, size_t?????? len)
??? Herror HReallocRLNum( Hproc_handle proc_handle, Hrlregion??? *region, size_t?????? len,
????????????????????????? Hrlregion??? **new_region)
??? Herror HFreeRL(?????? Hproc_handle proc_handle, Hrlregion??? *region)
Figure 3.5: General memory management for region data.
使用方便的例程HAllocRL、HAllocRLNum、HReallocRLNum和HFreeRL(見圖3.5)來處理基于HAlloc的永久區域數據。否則,它們的行為類似于HAllocRLTmp等。例如,使用HIncrRL(章節“HIncrRL”),HAllocRL分配更多的內存,參見此頁。注意,使用HReallocRLNum可以改變區域的大小(例如,和弦的數量)。
調試(Debugging)
HALCON內存管理提供了調試機制。這個調試是通過set_check('memory')打開的,可以通過set_check('~memory')關閉。每次釋放內存塊時,都會自動執行一些一致性檢查。此外,可以在任何時候使用特定的Extension Package Interface例程檢查內存塊的一致性以查找調試原因,見圖3.6。
Names
??? HTestMem, HTestPtr, HTestAllTmp, HTestTmp
Synopsis
??? #include "Halcon.h"
??? Herror HTestMem(void)
??? Herror HTestPtr(void????????? *pointer)
??? Herror HTestAllTmp(Hproc_handle? proc_handle)
??? Herror HTestTmp(Hproc_handle? proc_handle, void *pointer)
Figure 3.6: HALCON memory management: Check of consistency.
HTestMem檢查所有分配給HAlloc或HAllocLocal的內存,而HTestPtr只檢查指定的內存塊,這些內存塊必須分配給HAlloc。與此類似,HTestAllTmp檢查所有通過HAllocTmp分配的內存,HTestTmp檢查指定的塊。如果一致性檢查失敗,例程將返回錯誤代碼(H_ERR_ICM—內存不一致)。此外,如果全局變量HDoLowError設置為TRUE,它們會在stderr(類unix系統)或警告框(Windows)中顯示錯誤的描述。這個變量可以在應用程序中使用set_system操作符("do_low_error","true"/"false")來設置,也可以直接在新編寫的操作符中使用。
構造函數(Constructors)和Halcon操作符
HObject??????? image;
HTuple???????? barcode;
HObject??????? code_region;
HTuple???????? result;
ReadImage(&image, "barcode/ean13/ean1301");
CreateBarCodeModel(HTuple(), HTuple(), &barcode);
FindBarCode(image, &code_region, barcode, "EAN-13", &result);
Figure 5.4: Using FindBarCode via HBarCode, via HImage, or in the procedural approach.
如圖5.4所示,HALCON/c++參數類提供了額外的構造函數,這些構造函數基于合適的HALCON操作符。示例中使用的HImage和HBarCode構造函數分別基于ReadImage和CreateBarCodeModel。
經驗之談:如果類在操作符中只作為輸出參數出現,則會自動存在基于該操作符的構造函數。因此,可以基于CreateBarCodeModel構造HBarCode實例,如圖5.4所示,基于CreateShapeModel構造HShapeModel實例,基于OpenFramegrabber構造HFramegrabber實例等等。注意,對于存在許多這樣的操作符的類(例如HImage),只有一個具有明確形參列表的常用操作符子集實際用作構造函數。
此外,所有類都有空的構造函數來創建未初始化的對象。例如,你可以用默認構造函數創建一個HBarCode實例,然后使用CreateBarCodeModel初始化它,如下所示:
HBarCode?????? barcode;
barcode.CreateBarCodeModel(HTuple(), HTuple());
如果實例已經初始化,相應的數據結構將在重新構造和初始化它們之前自動銷毀(參見“析構函數和Halcon操作符”一節)。句柄類在“其他句柄類”一節中有更詳細的描述。
HImage image;????????????????? // still uninitialized
image.ReadImage("clip");
下面我們簡要介紹一下最重要的類。可以在HALCON操作符引用中找到可用構造函數的完整和最新列表,%HALCONROOT%\ \中對應的頭文件包括\cpp。
當然,您可以使用CloseWindow關閉窗口,然后使用OpenWindow再次打開它。與iconic的參數類相比,你可以通過HWindow的實例以直觀的方式調用“類構造函數”操作符OpenWindow,即修改調用實例;此外,還返回相應的句柄。HWindow在“Windows”一節中有更詳細的描述。
析構函數(Destructors)和Halcon操作符
所有的HALCON/c++類都提供了默認析構函數,它會自動釋放相應的內存。
封裝句柄的類的默認析構函數,例如HShapeModel或HFramegrabber,工作原理與ClearShapeModel或CloseFramegrabber類似。不需要調用這些操作符,因為你可以像“構造函數和Halcon操作符”一節中描述的那樣重新初始化實例。
基本上,我們要區分銷毀句柄和銷毀底層數據結構。數據結構可以通過兩種方式銷毀:
HObject、HRegion、HImage、HXLD、HXLDCont、HXLDPoly、HXLDModPara、HXLDPara、HXLDExtPara、操作符不能作為類成員使用,但將在釋放對象實例的資源時自動調用。這發生在垃圾收集的結束階段,或在顯式調用Dispose()方法時。
向量的析構(Destruction of Vectors)
如果HObjectVector或HTupleVector在以后的處理中不再需要它的內容,那么應該使用.dispose()清除它。
vectorObj.Dispose ();
總結
以上是生活随笔為你收集整理的HALCON: 内存管理(Memory Management)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多宫格视频是什么软件_抖音上的四/多宫格
- 下一篇: julia语言 python解释器_Ju