Halcon容易造成內(nèi)存增長(zhǎng)或泄露。怎么辦?
點(diǎn)擊下方卡片,關(guān)注“新機(jī)器視覺(jué)”公眾號(hào)
重磅干貨,第一時(shí)間送達(dá)
來(lái)源:
https://libaineu2004.blog.csdn.net/article/details/110877169
C#注意事項(xiàng)
1、變量用完之后,Dispose()和置Null。
C#會(huì)把hobject當(dāng)成一個(gè)小內(nèi)存占用對(duì)象,我的猜測(cè)是halcon對(duì)hobject中只是包裝了一個(gè)指針,然后C#語(yǔ)言無(wú)法將其識(shí)別為像bitmap那樣的對(duì)象,所以只要有hobject的地方都要謹(jǐn)慎考慮內(nèi)存釋放問(wèn)題。例如HOperatorSet.GenEmptyObj(out ho_Image); 這個(gè)應(yīng)該是去申請(qǐng)內(nèi)存的,然后使用先和使用后都要dispose,hobject就是一個(gè)封裝的指針對(duì)象。
在Halcon18以上版本,Halcon已經(jīng)提供了Dispose()方法進(jìn)行釋放,那么在低版本中HTuple類型占用的內(nèi)存怎么釋放呢?其實(shí),Halcon中提供一個(gè)叫UnPinTuple()的方法,該方法就是官方用來(lái)進(jìn)行釋放HTuple的!所以,使用后的變量如不再繼續(xù)使用的可以用該方法進(jìn)行清除釋放。
2、圖像盡量不要復(fù)制,固定在一個(gè)變量進(jìn)行處理。
3、在軟件內(nèi)存占用率高,并且軟件閑置的時(shí)候,調(diào)用Gc去清理。即:用完halcon對(duì)象,除了要dispose; 同時(shí)還需要用timer,去定時(shí) GC.Collect()。
4、不要用同一個(gè)變量作為輸入和輸出變量。
5、HObject 都不需要調(diào)用dispose,c# 用gc回收就可以了,除非你大量生成對(duì)象,這樣需要自己及時(shí)回收
6、C#中臨時(shí)Hobject對(duì)象每次用完養(yǎng)成手動(dòng)釋放的習(xí)慣就行,其他變量釋放不用管,在全局線程或定時(shí)器中加入C#自動(dòng)回收資源代碼就行
C++注意事項(xiàng)
1、原則上C++里HObject和HTuple變量,函數(shù)退出時(shí)會(huì)自動(dòng)析構(gòu),清空內(nèi)存。
如果非要自己手動(dòng)清除內(nèi)存,那不能用dispose()方法來(lái)釋放,因?yàn)镃++沒(méi)有這個(gè)接口。如果用戶想手動(dòng)釋放HObject和HTuple的內(nèi)存,應(yīng)該使用clear()方法。
2、創(chuàng)建模板匹配模型和測(cè)量助手等變量就必須手動(dòng)清空內(nèi)存,例如:
clear_all_templates()
clear_template()
clear_shape_model()
clear_ncc_model()
clear_all_ncc_models()
close_measure()
close_all_measures()
clear_all_component_models()
clear_all_training_components()
模板匹配算子占用內(nèi)存大
為了滿足亞像素的精度匹配,模板匹配算子通常會(huì)分配很大的內(nèi)存。操作系統(tǒng)通常推薦使用x64位的。
使用微軟的Process Explorer軟件可以看到內(nèi)存的占用情況:Private Bytes占用了1GB的內(nèi)存。

若內(nèi)存很大時(shí),還可以調(diào)用HOperatorSet.SetSystem("temporary_mem_cache", "false");關(guān)掉halcon的 cache試試。當(dāng)然,這很可能影響速度,所以不推薦這么做!
官方的內(nèi)存管理說(shuō)明書
1、來(lái)自官方的說(shuō)明書
C:\Program Files\MVTec\HALCON-18.11-Progress\doc\pdf\manuals\programmers_guide.pdf
C:/Program Files/MVTec/HALCON-18.11-Progress/doc/html/manuals/programmers_guide/programmers_guide_0000.html
2、內(nèi)容節(jié)選,5.4 Memory Management
All of HALCON's classes, i.e., not only HImage, HRegion, HTuple, HFramegrabber etc., but also the class HObject used when calling operators in the procedural approach, release their allocated resources automatically in their destructor (see also section “Destructors and Halcon Operators”). Furthermore, when constructing instances anew, e.g., by calling CreateBarCodeModel via an already initialized instance as mentioned in section “Constructors and Halcon Operators”, the already allocated memory is automatically released before reusing the instance. Thus, there is no need to call the operator ClearObj in HALCON/C++; what is more, if you do use it HALCON will complain about already released memory. To explicitly release the resources before the instance gets out of scope, you can call the method Clear() of the instance.
中文翻譯:
HALCON的所有類,不僅是HImage,HRegion,HTuple,HFramegrabber等,還包括在過(guò)程方法中調(diào)用運(yùn)算符時(shí)使用的HObject類,都將在其析構(gòu)函數(shù)中自動(dòng)釋放其分配的資源(另請(qǐng)參見(jiàn)“析構(gòu)函數(shù)和Halcon運(yùn)算符”部分) ”)。此外,當(dāng)重新構(gòu)造實(shí)例時(shí),例如,如“構(gòu)造函數(shù)和Halcon運(yùn)算符”部分所述,通過(guò)已初始化的實(shí)例調(diào)用CreateBarCodeModel,在重新使用實(shí)例之前,將自動(dòng)釋放已分配的內(nèi)存。因此,無(wú)需在HALCON / C ++中調(diào)用運(yùn)算符ClearObj;更重要的是,如果您使用它,HALCON將抱怨已經(jīng)釋放的內(nèi)存。要在實(shí)例超出范圍之前顯式釋放資源,可以調(diào)用實(shí)例的Clear()方法。
Windows中的進(jìn)程的Working Set,Private Bytes和Virtual Bytes
0)mmap (一種內(nèi)存映射文件的方法)
mmap將一個(gè)文件或者其它對(duì)象映射進(jìn)內(nèi)存。文件被映射到多個(gè)頁(yè)上,如果文件的大小不是所有頁(yè)的大小之和,最后一個(gè)頁(yè)不被使用的空間將會(huì)清零。mmap在用戶空間映射調(diào)用系統(tǒng)中作用很大。
1)Working Set是進(jìn)程和進(jìn)程所依賴的動(dòng)態(tài)庫(kù)和mmap的內(nèi)存占用的物理內(nèi)存大小??梢园阉闯梢粋€(gè)進(jìn)程能用到(但不一定會(huì)使用)的物理內(nèi)存。即不引起page fault異常就能夠訪問(wèn)的內(nèi)存。Working Set包含了可能被其他程序共享的內(nèi)存, 例如DLL就是一個(gè)典型的可能被其他程序共享的資源。所以所有進(jìn)程的Working Set加起來(lái)有可能大于實(shí)際的物理內(nèi)存。
2)Private Bytes是進(jìn)程占用內(nèi)存、進(jìn)程申請(qǐng)的內(nèi)存和進(jìn)程所依賴的動(dòng)態(tài)庫(kù)申請(qǐng)的內(nèi)存總和,不包括進(jìn)程所依賴的動(dòng)態(tài)庫(kù)占用的內(nèi)存、mmap的內(nèi)存。不一定在物理內(nèi)存上,可以被交換到磁盤上,所以可以比Working Set大。由于也包括進(jìn)程依賴動(dòng)態(tài)庫(kù)所申請(qǐng)的內(nèi)存,所以不能判斷內(nèi)存泄漏是由進(jìn)程導(dǎo)致的還是動(dòng)態(tài)庫(kù)導(dǎo)致的。Private Bytes只被本進(jìn)程用占用的虛擬地址空間,不包括其他進(jìn)程共享的內(nèi)存。Private Bytes既包括不引起page fault異常就能夠訪問(wèn)的內(nèi)存也包括引起page fault異常才能夠訪問(wèn)的內(nèi)存。所以一般Private Bytes大于Working Set。但是如果一個(gè)進(jìn)程和其他進(jìn)程共享較多內(nèi)存,也可能造成Working Set大于Private Bytes。
3)Virtual Byte是整個(gè)進(jìn)程占用的全部虛擬地址空間。32位Windows用戶模式下,進(jìn)程最大可以使用2GB,可以通過(guò)修改Boot.ini文件擴(kuò)展為最大可以使用到3GB。進(jìn)程和進(jìn)程所依賴的動(dòng)態(tài)庫(kù)和mmap的內(nèi)存一共所占用的虛擬內(nèi)存,包括在物理內(nèi)存上和磁盤上的總空間,所以一定比Working Set大,也比Private Bytes大。
4)Windows Task Manager中看到內(nèi)存使用量是Working Set。
本文僅做學(xué)術(shù)分享,如有侵權(quán),請(qǐng)聯(lián)系刪文。
