内存管理之引用计数

看到opencv的书上说,新版本的opencv2.2中mat类实现了引用计数,所以在赋值时任然是浅拷贝,但可作为函数返回值,以及类的成员函数返回值


Mat fun()

{

Mat result(
3,4,CV_8U);

returnreslut;

}



Mat img
=fun();

img.at
<char>(1,2);
如果没有引用计数,最后一句话在运行时,会出现内存错误。但有了引用计数,局部变量relult分配的内存,在函数fun退出时就不会释放掉,而要等到所有的引用对象退出作用域时,内存才会释放。

关于引用计数的概念,摘自大漠落日的博客(http://www.cppblog.com/smagle/archive/2010/07/23/120758.html

一、什么是引用计数?

引用计数是内存管理的一个技巧,可以看做是一种简单的垃圾回收机制,它允许多个拥有共同值的对象共享同一个对象。



二、为什么采用它?

对于没有垃圾自动回收机制的语言(如C/C++)和技术(如COM)来说,引用计数提供了一种简洁高效的内存管理方法。

  • 它简化了跟踪处理堆中对象的过程

一个对象被从堆中分配出来之后,我们需要明确的知道是谁拥有了这个对象,因为只有拥有这个对象的所有者能够销毁它。但我们在实际使用过程中, 这个对象可能被传递给另一个对象(例如通过传递指针参数),一旦这个过程复杂,我们很难确定谁最后拥有了这个对象。

使用引用计数就可以抛开这个问题,我们不需要再去关心谁拥有了这个对象,因为我们把管理权交割给了对象自己(这有点类似__stdcall和__cdecl两种函数调用约定)。当这个对象不再被任何人使用时,它自己负责销毁自己。

  • 简单并且高效

简单是特定时候增减一下对象的引用计数就可以了。高效是让多个具有相同值的对象共享同一个对象,省却了拷贝复值的过程,而且更加节省内存和宝贵的CPU时间。



三、谁都在使用它?

现在很多技术和编程语言都在使用它,如COM,Object-C等,如果我们愿意,我们可以在自己的程序中使用它。

  • COM

IUnknow提供了三个接口:QueryInterface、AddRef、Release。后面两个分别用来增减和减少通过QueryInterface获取的接口对象的引用计数,当内部的计数为0时,接口对象自动销毁自身。

  • COM的宿主DLL

这种类型的DLL包含四个导出函数:DLLRegisterServer、DLLUnregisterServer、DLLGetClassObject、DLLCanUnloadNoew。最后一个函数就是通过查看DLL维护的组件的计数值来决定这个DLL是否可以被CoFreeUnusedLibraries卸载掉。

  • Object-C

Object-C作为C的派生语言,它的内存管理彻底的采用了这个技巧。它的Foundation框架提供了是哪个方法:autoreleae、retain、release。第一个是将一个对象交由自动释放池管理,其实是自动调用了release;后面两个和COM中的最后两个是相同的,分别用来增加和减少引用计数。

以后有时间,在详细的去研究它,并简单地实现一下。虽然Mat实现了引用计数可以方便地作为返回值传递,但它作为浅拷贝始终存在一定的危险,尤其是将类的成员变量返回时,数据就可能存在多次修改。所以在这种情况小最好还是采用引用&。


原文链接: https://www.cnblogs.com/seacode/archive/2011/08/01/2124067.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/29725

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月8日 上午7:09
下一篇 2023年2月8日 上午7:09

相关推荐