我个人总结的Halcon内存管理心得笔记,关于C#/C++内存释放

简介: 我个人总结的Halcon内存管理心得笔记,关于C#/C++内存释放

尊重作者,支持原创,如需转载,请附上原地址:


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



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



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的内存。


image.png


若内存很大时,还可以调用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。


相关文章
|
1月前
|
C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(二)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
1月前
|
编译器 C++ 开发者
【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
8天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
27 4
|
1月前
|
存储 程序员 编译器
简述 C、C++程序编译的内存分配情况
在C和C++程序编译过程中,内存被划分为几个区域进行分配:代码区存储常量和执行指令;全局/静态变量区存放全局变量及静态变量;栈区管理函数参数、局部变量等;堆区则用于动态分配内存,由程序员控制释放,共同支撑着程序运行时的数据存储与处理需求。
102 21
|
28天前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
1月前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
|
1月前
|
存储 C语言 C++
【C++打怪之路Lv6】-- 内存管理
【C++打怪之路Lv6】-- 内存管理
37 0
【C++打怪之路Lv6】-- 内存管理
|
1月前
|
存储 C语言 C++
【C/C++内存管理】——我与C++的不解之缘(六)
【C/C++内存管理】——我与C++的不解之缘(六)
|
1月前
|
程序员 C语言 C++
C++入门5——C/C++动态内存管理(new与delete)
C++入门5——C/C++动态内存管理(new与delete)
67 1
|
1月前
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
157 1