我个人总结的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。


相关文章
|
10月前
|
存储 程序员 编译器
玩转C++内存管理:从新手到高手的必备指南
C++中的内存管理是编写高效、可靠程序的关键所在。C++不仅继承了C语言的内存管理方式,还增加了面向对象的内存分配机制,使得内存管理既有灵活性,也更加复杂。学习内存管理不仅有助于提升程序效率,还有助于理解计算机的工作原理和资源分配策略。
|
存储 前端开发 Java
Kotlin教程笔记 - MVVM架构怎样避免内存泄漏
Kotlin教程笔记 - MVVM架构怎样避免内存泄漏
167 2
|
6月前
|
C语言 C++
c与c++的内存管理
再比如还有这样的分组: 这种分组是最正确的给出内存四个分区名字:栈区、堆区、全局区(俗话也叫静态变量区)、代码区(也叫代码段)(代码段又分很多种,比如常量区)当然也会看到别的定义如:两者都正确,记那个都选,我选择的是第一个。再比如还有这样的分组: 这种分组是最正确的答案分别是 C C C A A A A A D A B。
127 1
|
9月前
|
存储 Linux C语言
C++/C的内存管理
本文主要讲解C++/C中的程序区域划分与内存管理方式。首先介绍程序区域,包括栈(存储局部变量等,向下增长)、堆(动态内存分配,向上分配)、数据段(存储静态和全局变量)及代码段(存放可执行代码)。接着探讨C++内存管理,new/delete操作符相比C语言的malloc/free更强大,支持对象构造与析构。还深入解析了new/delete的实现原理、定位new表达式以及二者与malloc/free的区别。最后附上一句鸡汤激励大家行动缓解焦虑。
|
存储 缓存 C语言
【c++】动态内存管理
本文介绍了C++中动态内存管理的新方式——`new`和`delete`操作符,详细探讨了它们的使用方法及与C语言中`malloc`/`free`的区别。文章首先回顾了C语言中的动态内存管理,接着通过代码实例展示了`new`和`delete`的基本用法,包括对内置类型和自定义类型的动态内存分配与释放。此外,文章还深入解析了`operator new`和`operator delete`的底层实现,以及定位new表达式的应用,最后总结了`malloc`/`free`与`new`/`delete`的主要差异。
226 3
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
653 1
|
存储 C语言 C++
【C++打怪之路Lv6】-- 内存管理
【C++打怪之路Lv6】-- 内存管理
167 0
【C++打怪之路Lv6】-- 内存管理
|
存储 前端开发 Java
Kotlin教程笔记 - MVVM架构怎样避免内存泄漏
Kotlin教程笔记 - MVVM架构怎样避免内存泄漏
164 1
|
存储 前端开发 Java
Kotlin教程笔记 - MVVM架构怎样避免内存泄漏
Kotlin教程笔记 - MVVM架构怎样避免内存泄漏
|
算法 安全 测试技术
C#——刘铁猛笔记
C#——刘铁猛笔记
339 0