Halcon容易造成内存增长或泄露。怎么办?

新机器视觉

共 3638字,需浏览 8分钟

 ·

2022-05-31 10:27

点击下方卡片,关注“新机器视觉”公众号

重磅干货,第一时间送达

来源:

https://libaineu2004.blog.csdn.net/article/details/110877169


C#注意事项


1、变量用完之后,Dispose()和置Null。


C#会把hobject当成一个小内存占用对象,我的猜测是halcon对hobject中只是包装了一个指针,然后C#语言无法将其识别为像bitmap那样的对象,所以只要有hobject的地方都要谨慎考虑内存释放问题。例如HOperatorSet.GenEmptyObj(out ho_Image); 这个应该是去申请内存的,然后使用先和使用后都要dispose,hobject就是一个封装的指针对象。


在Halcon18以上版本,Halcon已经提供了Dispose()方法进行释放,那么在低版本中HTuple类型占用的内存怎么释放呢?其实,Halcon中提供一个叫UnPinTuple()的方法,该方法就是官方用来进行释放HTuple的!所以,使用后的变量如不再继续使用的可以用该方法进行清除释放。


2、图像尽量不要复制,固定在一个变量进行处理。


3、在软件内存占用率高,并且软件闲置的时候,调用Gc去清理。即:用完halcon对象,除了要dispose; 同时还需要用timer,去定时 GC.Collect()。


4、不要用同一个变量作为输入和输出变量。


5、HObject 都不需要调用dispose,c# 用gc回收就可以了,除非你大量生成对象,这样需要自己及时回收

6、C#中临时Hobject对象每次用完养成手动释放的习惯就行,其他变量释放不用管,在全局线程或定时器中加入C#自动回收资源代码就行



C++注意事项


1、原则上C++里HObject和HTuple变量,函数退出时会自动析构,清空内存。


如果非要自己手动清除内存,那不能用dispose()方法来释放,因为C++没有这个接口。如果用户想手动释放HObject和HTuple的内存,应该使用clear()方法。


2、创建模板匹配模型和测量助手等变量就必须手动清空内存,例如:


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



模板匹配算子占用内存大


为了满足亚像素的精度匹配,模板匹配算子通常会分配很大的内存。操作系统通常推荐使用x64位的。


使用微软的Process Explorer软件可以看到内存的占用情况:Private Bytes占用了1GB的内存。



若内存很大时,还可以调用HOperatorSet.SetSystem("temporary_mem_cache", "false");关掉halcon的 cache试试。当然,这很可能影响速度,所以不推荐这么做!



官方的内存管理说明书


1、来自官方的说明书


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、内容节选,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等,还包括在过程方法中调用运算符时使用的HObject类,都将在其析构函数中自动释放其分配的资源(另请参见“析构函数和Halcon运算符”部分) ”)。此外,当重新构造实例时,例如,如“构造函数和Halcon运算符”部分所述,通过已初始化的实例调用CreateBarCodeModel,在重新使用实例之前,将自动释放已分配的内存。因此,无需在HALCON / C ++中调用运算符ClearObj;更重要的是,如果您使用它,HALCON将抱怨已经释放的内存。要在实例超出范围之前显式释放资源,可以调用实例的Clear()方法。



Windows中的进程的Working Set,Private Bytes和Virtual Bytes


0)mmap (一种内存映射文件的方法)

mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。mmap在用户空间映射调用系统中作用很大。


1)Working Set是进程和进程所依赖的动态库和mmap的内存占用的物理内存大小。可以把它看成一个进程能用到(但不一定会使用)的物理内存。即不引起page fault异常就能够访问的内存。Working Set包含了可能被其他程序共享的内存, 例如DLL就是一个典型的可能被其他程序共享的资源。所以所有进程的Working Set加起来有可能大于实际的物理内存。


2)Private Bytes是进程占用内存、进程申请的内存和进程所依赖的动态库申请的内存总和,不包括进程所依赖的动态库占用的内存、mmap的内存。不一定在物理内存上,可以被交换到磁盘上,所以可以比Working Set大。由于也包括进程依赖动态库所申请的内存,所以不能判断内存泄漏是由进程导致的还是动态库导致的。Private Bytes只被本进程用占用的虚拟地址空间,不包括其他进程共享的内存。Private Bytes既包括不引起page fault异常就能够访问的内存也包括引起page fault异常才能够访问的内存。所以一般Private Bytes大于Working Set。但是如果一个进程和其他进程共享较多内存,也可能造成Working Set大于Private Bytes。


3)Virtual Byte是整个进程占用的全部虚拟地址空间。32位Windows用户模式下,进程最大可以使用2GB,可以通过修改Boot.ini文件扩展为最大可以使用到3GB。进程和进程所依赖的动态库和mmap的内存一共所占用的虚拟内存,包括在物理内存上和磁盘上的总空间,所以一定比Working Set大,也比Private Bytes大。


4)Windows Task Manager中看到内存使用量是Working Set。


本文仅做学术分享,如有侵权,请联系删文。

—THE END—
浏览 427
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报