• 恒生UFX接口引用计数心得


    本文介绍在基于恒生T2SDK基础上开发对接UFX柜台时,有关引用计数的一些心得体会。
    下面以配置接口和连接接口为例子来介绍,下面是文档介绍:

    创建配置接口说明:

    3.1.2 创建配置接口(NewConfig)
    函数原型:
    CConfigInterface* FUNCTION_CALL_MODE NewConfig();
    输入参数:
    参数名称 参数说明 用法

    返回:
    新的连接配置项接口。
    用法说明:
    通过返回的新的连接配置项接口,设置相应的连接属性,具体的接口说明参照下面的CConfigInterface接口说明。
    注意
    NewConfig()返回的接口,必须调用AddRef,否则调用Release接口就无法释放

    创建连接接口说明:

    3.1.3 创建连接接口(NewConnection)
    函数原型:
    CConnectionInterface* FUNCTION_CALL_MODE NewConnection(CConfigInterface *lpConfig);
    输入参数:
    参数名称 参数说明 用法
    CConfigInterface *lpConfig 配置对象,通过NewConfig()返回 输入参数
    返回:
    新的连接接口,所有发包收包都是建立在连接接口之上。
    用法说明:
    通过返回的连接接口指针,就可以访问服务端,发功能号,收应答,所有操作都是基于连接。
    注意
    NewConnection ()返回的接口,必须调用AddRef,否则调用Release接口就无法释放

    文档指出,在使用NewXX类返回的指针时,必须调用AddRef,在不需要使用时,调用Release来释放引用计数。看到这里,心里就有一个疑问,在调用CConnectionInterface* pConnect = NewConnection(lpConfig)时,lpConfig的引用计数会增加吗?如果此时增加,那么什么时候释放呢?

    原理分析

    引用计数往往和一块申请好的内存相互关联,在这块内存被申请者申请后(此处是NewConfig,引用计数为1),传递给其他模块使用(此处为NewConnection的入参)时,需要由其他模块对这块内存维护引用计数。从这个角度出发,NewConnection操作会增加传入指针的引用计数,而对应的Release操作,会减少传入指针的引用计数。

    实践验证

    由于T2SDK提供的dll未附带调试信息,因此,采用内存对比法来验证调用Release函数时,是否真的释放内存。为了突出重点,此处只选用NewConfigNewConooection这两个函数来验证。

    • 第一步
    
    CConfigInterface * lpConfig = NewConfig();   // 创建配置接口
    lpConfig->AddRef();
    //lpConfig->AddRef();
    lpConfig->Release();
    //lpConfig->Release();
    
    

    方法:观察 lpConfig 所指向的内存有效性来验证释放内存有效性。

    结论:AddRef和Release要一对一调用才能正确释放内存,两次AddRef对应一次Release,内存不会释放,一次AddRef对应两次Release,会触发异常。

    • 第二步
    
    CConfigInterface * lpConfig = NewConfig();   // 创建配置接口
    lpConfig->AddRef();
    
    CConnectionInterface* lpConnect = NewConnection(lpConfig);  // 创建连接接口 
    lpConnect->AddRef();
    
    // 类型1
    lpConfig->Release();
    lpConfig->Release();  // 调用此句,内存释放,说明 NewConnection 内部在创建成功的情况下,会对入参增加引用计数
    
    // 类型2
    lpConnect->Release();
    lpConfig->Release();
    lpConfig->Release();  // 调用到此处会崩溃,说明调用 lpConnect->Release() 时,会对之前的入参减少引用计数
    
    // 类型3
    lpConnect->Release();
    lpConnect = NULL;
    lpConfig->Release();  // 能够正常释放内存
    lpConfig = NULL;	  // 防止后续代码误用
    
    

    小结,NewConnection函数以及其他New类型函数,对传入的NewXXX类型入参会增加引用计数,调用Release函数时,会减少对应的引用计数。从语义上来说,调用Release表明当前模块不再关心该内存内容,以防后续业务代码误用,最好将对应指针置为空。

    如果是NewXXX返回的句柄在后续业务中需要继续使用,那么将此对象保存为成员函数对象,在整个生命周期中都维持有效,直到最终退出时,再释放对应内存。

  • 相关阅读:
    JQuery EasyUI的datagrid的使用方式总结
    重新=》easyui DataGrid是否可以动态的改变列显示的顺序
    easyui datagrid 列拖动
    MTK平台下Battery驱动分析
    Shell编程——Shell中的数学运算
    新产品为了效果,做的比較炫,用了非常多的图片和JS,所曾经端的性能是非常大的问题,分篇记录前端性能优化的一些小经验。
    iOS内存管理机制解析之MRC手动引用计数机制
    微软下一代站点开发框架:ASP.NET MVC 6 新特性揭秘
    JS简单正则得到字符串中特定的值
    数据结构和算法面试总结
  • 原文地址:https://www.cnblogs.com/cherishui/p/10429970.html
Copyright © 2020-2023  润新知