实现引用计数并不难,但在什么层次上进行引用计数呢?

依照com规范,一个com组件能够实现多个com对象。而且每一个com对象又能够支持多个com接口,这样的层次结构为我们实现引用计数提供了多种选择方案。

我们能够选择在com组件一级实现引用计数,也能够选择在com对象一级实现引用计数。甚至能够为对象的每一个接口设置一个引用计数。

三张选择方案都有各自的优缺点。

1)设置一个针对整个组件全局的引用计数。

在实现组件时,我们用一个全局整数变量记录引用计数值,当组件被初始装入内存时,该计数值为0。当有对象被创建时,计数值開始添加,在整个组件被使用的过程中,计数值一直保持大于0,当组件中的全部对象都被用完之后。计数值应该减回到0,于是组件模块九能够从内存中卸出。

这样的引用计数能够控制组件模块的生存周期,但不能控制com对象的生存周期。试想,假设这个组件程序在执行过程中产生了两个com对象,无论是同一类的对象还是不同类的对象,当某一个对象被减1时,由于减1是对全局引用计数进行的。所以它无法从引用计数上推断是否该对象已经不再被使用了。必须等到全部的对象都被使用完了之后,即全局引用计数减到0时。全部的对象才干够一起被释放。

这样做自然减少了系统资源的利用率。这个缺点我们能够称之为“计数分辨率太粗”。由于计数值包括了全部组件全部接口的使用记录,它只控制组件模块的生存期。

2)为每一个com对象设置一个引用计数。在实现com对象时,用一个与组件对象具有相同生存期的整数变量记录引用计数值,当对象被创建时。计数值開始从0添加;仅仅要对象还在被客户程序使用,则计数值大于0。当客户不再使用该对象时,计数值应该减回到0,于是对象所占用的资源被释放掉以便为系统又一次使用。

在对象一级设置引用计数能够避免”计数分辨率太粗“的缺点,对于多个对象的组件程序能够有效地提高系统资源利用率。但每当一个对象被释放掉之后,它必须通知组件程序。假设组件程序发现已经没有对象存在了。则组件模块应该能够从内存中卸出。因此,组件程序应该保持一份有效对象的记录,能够用一个全局的对象计数值来控制组件生存周期。

当对象被释放时,同一时候组件的对象计数值也减1,假设对象计数值为0,则表明组件模块能够从内存中卸出。

3)为每一个接口设置一个引用计数。由于客户通过接口指针与组件对象进行通信。所以为每一个接口设置引用计数能够跟踪客户对com对象的使用情况。客户并不一定用到对象全部的接口,对于实现多个接口的对象,非常有可能某些接口没有被客户使用到,那么只与这些接口相关的资源就能够不被占用。

在接口一级设置引用计数使得“计数分辨率”非常细,通过接口的引用计数能够有效地掌握客户对接口的使用情况,这对于我们调试组件程序和分析客户程序的使用情况非常有帮助。但每当一个接口的引用计数减回到0时,它必须给对象发出通知,对象在接到通知后,须要怕安段是否全部的接口计数都为0,假设是,对象就必须把自己给释放掉。完毕清除工作。再进一步通知组件程序,组件程序接到通知后推断是否全部的对象都已经被清除。假设是。则它能够被卸出内存。

由于这样的通知时必须的,所以在接口一级实现引用计数有“计数分辨率太细”之嫌。

假设在组件一级实现引用计数。自然能够选择全局变量;假设在对象一级实现引用计数,我们能够使用C++类的成员变量;假设在接口一级实现引用计数。我们能够为对象实现的每个接口设置一个类成员变量作为引用计数变量。

通过上面的分析,从这样的的角度出发,比較合理的方案是採用对象一级的引用计数以便控制对象和组件的生存周期。

com关于引用计数的更多相关文章

  1. Objective-C内存管理之引用计数

    初学者在学习Objective-c的时候,很容易在内存管理这一部分陷入混乱状态,很大一部分原因是没有弄清楚引用计数的原理,搞不明白对象的引用数量,这样就当然无法彻底释放对象的内存了,苹果官方文档在内存 ...

  2. swift学习笔记5——其它部分(自动引用计数、错误处理、泛型...)

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  3. C++ 引用计数技术及智能指针的简单实现

    一直以来都对智能指针一知半解,看C++Primer中也讲的不够清晰明白(大概是我功力不够吧).最近花了点时间认真看了智能指针,特地来写这篇文章. 1.智能指针是什么 简单来说,智能指针是一个类,它对普 ...

  4. 【Python】引用计数

    一.概述 要保持追踪内存中的对象,Python使用了引用计数这一简单的技术. 二.引用计数的增减 2.1 增加引用计数 当对象被创建并(将其引用)赋值给变量时,该对象的引用计数被设置为1. 对象的引用 ...

  5. iOS开发--引用计数与ARC

    以下是关于内存管理的学习笔记:引用计数与ARC. iOS5以前自动引用计数(ARC)是在MacOS X 10.7与iOS 5中引入一项新技术,用于代替之前的手工引用计数MRC(Manual Refer ...

  6. Objective-C内存管理之-引用计数

    本文会继续深入学习OC内存管理,内容主要参考iOS高级编程,Objective-C基础教程,疯狂iOS讲义,是我学习内存管理的笔记 内存管理 1 内存管理的基本概念 1.1 Objective-C中的 ...

  7. 第3月第2天 find symbolicatecrash 生产者-消费者 ice 引用计数

    1.linux find export find /Applications/Xcode.app/ -name symbolicatecrash -type f export DEVELOPER_DI ...

  8. swif-自动引用计数

    import UIKit /* class Person { let name: String //强引用 init(name: String) { self.name = name print(&q ...

  9. OC中的自动引用计数

    目录: 1,自动引用计数的定义 2,强引用和弱引用 3,类比手动引用 4,循环引用 5,CoreFoundation 内容: 自动引用计数的定义: (Automatic Reference Count ...

  10. ATL是如何实现线程安全的引用计数和多线程控制的

    ATL是如何实现线程安全的引用计数和多线程控制的 正如标题所示,这是我经常被问到的一个问题,而每次我都从头开始给人说一次,其实说来过程理解起来的确有点复杂. 我们的每一个ATL Server Obje ...

随机推荐

  1. linq 分组

    var data = from r in listRecords group r by new { r.CampaignId, r.CityId, r.Gift_DistributorId, r.Pr ...

  2. [ NOI 2005 ] 聪聪与可可

    \(\\\) \(Description\) 一张\(N\)个点,\(M\)条边的有向图中,猫在\(A\)点,鼠在\(B\)点,每一秒两者按照以下规则移动: 猫先走去往老鼠所在地的最短路,可以走一步或 ...

  3. android shape stroke只绘制一边或者某几边

    <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android=" ...

  4. win32之bitmap篇

    先讲一下LoadBitmap的用法,代码如下: PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd,&ps); HDC hMemDC = CreateCompa ...

  5. SPA设计架构

    1.SPA是采用单页应用(Single Page Application)的方式来开发 2.SPA的框架有如Augular.js.Vue.js等.

  6. PHP 之二位数组根据某个字段排序封装

    /** * @param $array * @param $keys * @param string $sort * @return array */ function arraySort($arra ...

  7. CAD动态绘制样条线(com接口)

    主要用到函数说明: _DMxDrawX::SendStringToExecuteFun 把命令当着函数执行,可以传参数.详细说明如下: 参数 说明 IDispatch* pParam 命令参数,IMx ...

  8. vivado2018.3 与 modelsim联合仿真

    我用的是目前最新版本的软件,vivado2018.3与modelsim10.6d.废话不多说,直接上操作 1.modelsim编译vivado库 1)双击启动vivado软件,如下图操作 2)Simu ...

  9. HDU 2414 Chessboard Dance(模拟题,仅此纪念我的堕落)

    题目 模拟题也各种wa,我最近真的堕落了,,,,,智商越来越为负数了!!!!!!!! #include<stdio.h> #include<string.h> #include ...

  10. webpack打包出错,通过babel将es6转es5的出错。

    错误信息如下: 解决方法: 1,先安装babel-preset-es2015到项目中, cnpm install babel-preset-es2015 --save-dev2,在项目根目录中新建一个 ...