掌桥专利:专业的专利平台
掌桥专利
首页

一种资源回收方法、装置、电子设备及存储介质

文献发布时间:2023-06-19 19:35:22


一种资源回收方法、装置、电子设备及存储介质

技术领域

本申请涉及计算机技术领域,尤其涉及一种资源回收方法、装置、电子设备及存储介质。

背景技术

目前RAII原理只能对栈上的资源进行管理,不在栈上的资源,比如通过new操作符new出来的资源,或者通过malloc申请的资源,或者是从系统申请获取的资源则不能进行回收,需要手动释放。但实际应用场景中,在一个函数进入后申请了一个资源,比如打开了一个文件,在读取文件的过程中可能因为文件内容或者某些原因导致当前程序的执行被中断并返回了,程序员在写这种代码的时候,有时候为了捕获这种特殊情况,需要很多的工作量,比如添加try_catch或者判断在每一个可能退出的地方加上关闭句柄或者释放资源的代码,但此种做法难以避免会因为疏忽而遗漏或者忘记,导致程序产生内存泄漏。

发明内容

为了解决如何避免资源泄漏的技术问题,本申请提供了一种资源回收方法、装置、电子设备及存储介质。

第一方面,本申请提供了一种资源回收方法,包括:

构建目标对象;所述目标对象为栈上的变量;所述目标对象中存储有目标函数的仿函数对象;所述仿函数对象用于对所述目标函数的资源进行回收;

确定所述目标对象执行结束,析构所述目标对象;

调用所述仿函数对象,对析构所述目标对象过程中所述目标函数释放的资源进行回收;

可选地,构建目标对象,包括:

定义第一对象,所述第一对象中存储一个仿函数;

获取回收目标函数资源的目标代码段;

将所述目标代码段封装在所述仿函数中;将所述仿函数作为所述仿函数对象,将所述第一对象作为所述目标对象;

可选地,确定所述目标对象执行结束,析构所述目标对象,包括:

确定所述目标函数执行结束,触发资源获取即初始化RAII机制,基于RAII技术对所述目标对象进行析构;

可选地,确定所述目标函数执行结束,包括:

获取所述目标函数的结束信息;

根据所述结束信息确定所述目标函数执行结束;所述结束信息包括执行完成或异常中断;

可选地,构建目标对象之前,所述方法还包括:构建所述目标函数;

可选地,所述目标对象包括Scopeguard对象。

第二方面,本申请提供了一种资源回收装置,包括:

构建模块,用于构建目标对象;所述目标对象为栈上的变量;所述目标对象中存储有目标函数的仿函数对象;所述仿函数对象用于对所述目标函数的资源进行回收;

析构模块,用于确定所述目标对象执行结束,析构所述目标对象;

回收模块,用于调用所述仿函数对象,对析构所述目标对象过程中所述目标函数释放的资源进行回收;

可选地,所述构建模块,具体用于定义第一对象,所述第一对象中存储一个仿函数;获取回收目标函数资源的目标代码段;将所述目标代码段封装在所述仿函数中;将所述仿函数作为所述仿函数对象,将所述第一对象作为所述目标对象。

第三方面,本申请提供了一种电子设备,包括处理器、通信接口、存储器和通信总线,其中,处理器,通信接口,存储器通过通信总线完成相互间的通信;

存储器,用于存放计算机程序;

处理器,用于执行存储器上所存放的程序时,实现第一方面任一项实施例所述的资源回收方法的步骤。

第四方面,本申请提供了一种计算机可读存储介质,其上存储有计算机程序,所述计算机程序被处理器执行时实现如第一方面任一项实施例所述的资源回收方法的步骤。

本申请实施例提供的上述技术方案与现有技术相比具有如下优点:

本申请实施例提供的该方法,构建目标对象;所述目标对象为栈上的变量;所述目标对象中存储有目标函数的仿函数对象;所述仿函数对象用于对所述目标函数的资源进行回收;确定所述目标对象执行结束,析构所述目标对象;调用所述仿函数对象,对析构所述目标对象过程中所述目标函数释放的资源进行回收。该方法,目标对象是一个栈上的变量,将对目标函数进行资源回收的仿函数对象配置于目标对象,当目标对象执行结束时触发析构,进而调用仿函数对象进行资源回收,从而避免了资源的泄漏。

附图说明

此处的附图被并入说明书中并构成本说明书的一部分,示出了符合本发明的实施例,并与说明书一起用于解释本发明的原理。

为了更清楚地说明本发明实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,对于本领域普通技术人员而言,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。

图1为本申请一个实施例提供的一种资源回收方法的系统架构图;

图2为本申请一个实施例提供的一种资源回收方法的流程示意图;

图3为本申请一个实施例提供的一种资源回收装置的结构示意图;

图4为本申请一个实施例提供的一种电子设备的结构示意图。

具体实施方式

为使本申请实施例的目的、技术方案和优点更加清楚,下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例是本申请的一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有做出创造性劳动的前提下所获得的所有其他实施例,都属于本申请保护的范围。

本申请第一实施例提供了一种资源回收方法,该方法可以应用于如图1所示的系统架构,该系统架构中至少包括终端101和服务器102,该终端101和服务器102建立通信连接。

该方法可应用于该系统架构中的终端101或者服务器102,其中,终端101可以是台式电脑、平板电脑、笔记本、超级计算机等设备,服务器102可以是本地服务器,也可以是云端服务器,或者也可以是服务器集群。当应用于终端101时,该系统架构也可以仅包括终端101,不作限制。

接下来,基于该系统架构,对该资源回收方法进行详细说明,如图2,一种资源回收方法,包括:

步骤201,构建目标对象,目标对象为栈上的变量,目标对象中存储有目标函数的仿函数对象,仿函数对象用于对目标函数的资源进行回收。

其中,构建目标对象,可以具体包括:定义第一对象,第一对象中存储一个仿函数,获取回收目标函数资源的目标代码段,将目标代码段封装在仿函数中;将仿函数作为仿函数对象,将第一对象作为目标对象。

在不同的编程环境中,目标对象的称呼略有不同,比如在C++语言中,目标对象可以是Scopeguard对象。ScopeGuard对象在出作用域后,可以自动执行某段代码,比如,在目标对象执行析构函数时,可以自动执行回收目标函数资源的仿函数。

本实施例中,可以将需要释放资源的代码段通过lambda的方式构建一个仿函数对象,并存储在scopeguard中,当然,通过代码段构建仿函数对象还可以是其他方式,不作限制。

需要说明的是,作用域(scope)在许多程序设计语言中非常重要。通常来说,一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强程序的可靠性,减少名字冲突。

步骤202,确定目标对象执行结束,析构目标对象。

步骤203,调用仿函数对象,对析构目标对象过程中目标函数释放的资源进行回收。

其中,确定目标对象执行结束,析构目标对象,可以具体包括:确定目标函数执行结束,触发资源获取即初始化RAII机制,基于RAII技术对目标对象进行析构。

本实施例中,可以采用资源获取即初始化(Resource Acquisition IsInitialization,简称RAII)机制,虽然目前RAII原理只能对栈上的资源进行管理,不在栈上的资源,比如通过new操作符new出来的资源,或者通过malloc申请的资源,或者是从系统申请获取的资源则不能进行回收,需要手动释放。但是,本实施例中,将目标函数的仿函数对象配置于了目标对象中,即使目标函数不是栈上的资源,也可以在目标函数执行结束时,基于RAII对目标对象进行析构,从而调用仿函数对目标函数释放的资源进行回收,可避免异常情况下的资源泄漏。

本实施例中,当scopegurad因RAII退出当前函数的作用域的时候,会自动触发其析构,从而调用到对应的仿函数对象,从而正确的释放资源。

本实施例中,将资源需要释放的代码注册给ScopeGuard,由于scopeGuard是一个栈上的变量,当函数栈在销毁的时候便会触发RAII,从而触发scopeguard的析构,最后调用到需要释放资源的代码,从而避免内存泄漏。能够有效的防止申请到的资源或者创建在堆上的数据因为非正常路径返回,而引发的内存泄漏问题。并且,本实施例中,由于采用仿函数对象方式,将需要析构内容通过创建到仿函数对象并存储在scopeguard中,当scopeguard被析构的时候调用其存储的仿函数对象中的析构代码,具备通用性强,且对原有代码侵入少。

一个实施例中,确定目标函数执行结束,包括:获取目标函数的结束信息,根据结束信息确定目标函数执行结束,其中,结束信息包括执行完成或异常中断,异常中断可以是中途退出或者异常退出。

一个实施例中,构建目标对象之前,方法还包括:构建目标函数。其中,目标函数可以是不在栈上的资源,比如通过new操作符new出来的资源,或者通过malloc申请的资源,或者是从系统申请获取的资源,当然,目标函数也可以是栈上的资源,不作限制。

在上述任一实施例中,本申请利用RAII原理,构建一个类,并存储一个仿函数对象,并且接收一个资源回收的代码段(可以是将用户给出的代码段通过lamdba生成一个仿函数,并实例化到Scopegurad中),并且在scopeguard类的析构中调用用于回收资源的仿函数。本实施例利用RAII的机制,实现资源的动态回收,避免作用域中途退出或者异常退出产生资源泄露问题,当然,本申请主要应用于函数内部。

在上述任一实施例中,定义一个ScopeGuard对象,并存储一个仿函数对象,把要析构的代码段可以通过宏的方式创建一个仿函数对象,并存储到ScopeGuard对象的仿函数对象中,函数执行结束时,会触发RAII机制,这个机制会促使Scopeguard对象调用析构,析构会执行其内部的仿函数进行资源回收。

具体地,可以是定义一个宏,该宏第一步会定义一个Scopeguard对象并将宏后面{}内部的代码封装在一个仿函数对象中。当该模块代码被中断,则会触发RAII,从而析构Scopeguard对象,最后调用仿函数的内容,从而达到对需要资源释放的对象进行资源回收。

需要说明的是,对于不同的目标函数,可根据需要选择free、delete或者close等进行资源回收,不作限制。

基于同一技术构思,本申请第二实施例提供了一种资源回收装置,如图3,所述装置包括:

构建模块301,用于构建目标对象;所述目标对象为栈上的变量;所述目标对象中存储有目标函数的仿函数对象;所述仿函数对象用于对所述目标函数的资源进行回收;

析构模块302,用于确定所述目标对象执行结束,析构所述目标对象;

回收模块303,用于调用所述仿函数对象,对析构所述目标对象过程中所述目标函数释放的资源进行回收。

该装置中,目标对象是一个栈上的变量,将对目标函数进行资源回收的仿函数对象配置于目标对象,当目标对象执行结束时触发析构,进而调用仿函数对象进行资源回收,从而避免了资源的泄漏。

一个实施例中,所述构建模块,具体用于定义第一对象,所述第一对象中存储一个仿函数;获取回收目标函数资源的目标代码段;将所述目标代码段封装在所述仿函数中;将所述仿函数作为所述仿函数对象,将所述第一对象作为所述目标对象。

一个实施例中,所述析构模块,具体用于确定所述目标函数执行结束,触发资源获取即初始化RAII机制,基于RAII技术对所述目标对象进行析构。其中,确定所述目标函数执行结束,包括:获取所述目标函数的结束信息;根据所述结束信息确定所述目标函数执行结束;所述结束信息包括执行完成或异常中断。

一个实施例中,所述装置还包括配置模块,所述配置模块用于构建目标函数。

该装置,利用RAII原理,构建一个类,并存储一个仿函数对象,并且接收一个资源回收的代码段(可以是将用户给出的代码段通过lamdba生成一个仿函数,并实例化到Scopegurad中),并且在scopeguard类的析构中调用用于回收资源的仿函数。本实施例利用RAII的机制,实现资源的动态回收,避免作用域中途退出或者异常退出产生资源泄露问题。

如图4所示,本申请第三实施例提供了一种电子设备,包括处理器111、通信接口112、存储器113和通信总线114,其中,处理器111,通信接口112,存储器113通过通信总线114完成相互间的通信,

存储器113,用于存放计算机程序;

在一个实施例中,处理器111,用于执行存储器113上所存放的程序时,实现前述任意一个方法实施例提供的资源回收方法,包括:

构建目标对象;所述目标对象为栈上的变量;所述目标对象中存储有目标函数的仿函数对象;所述仿函数对象用于对所述目标函数的资源进行回收;

确定所述目标对象执行结束,析构所述目标对象;

调用所述仿函数对象,对析构所述目标对象过程中所述目标函数释放的资源进行回收。上述终端提到的通信总线可以是外设部件互连标准(Peripheral ComponentInterconnect,简称PCI)总线或扩展工业标准结构(Extended Industry StandardArchitecture,简称EISA)总线等。该通信总线可以分为地址总线、数据总线、控制总线等。为便于表示,图中仅用一条粗线表示,但并不表示仅有一根总线或一种类型的总线。

通信接口用于上述终端与其他设备之间的通信。

存储器可以包括随机存取存储器(Random Access Memory,简称RAM),也可以包括非易失性存储器(non-volatile memory),例如至少一个磁盘存储器。可选的,存储器还可以是至少一个位于远离前述处理器的存储装置。

上述的处理器可以是通用处理器,包括中央处理器(Central Processing Unit,简称CPU)、网络处理器(Network Processor,简称NP)等;还可以是数字信号处理器(Digital Signal Processing,简称DSP)、专用集成电路(Application SpecificIntegrated Circuit,简称ASIC)、现场可编程门阵列(Field-Programmable Gate Array,简称FPGA)或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件。

本申请第四实施例还提供了一种计算机可读存储介质,其上存储有计算机程序,所述计算机程序被处理器执行时实现如前述任意一个方法实施例提供的资源回收方法的步骤。

在上述实施例中,可以全部或部分地通过软件、硬件、固件或者其任意组合来实现。当使用软件实现时,可以全部或部分地以计算机程序产品的形式实现。所述计算机程序产品包括一个或多个计算机指令。在计算机上加载和执行所述计算机程序指令时,全部或部分地产生按照本申请实施例所述的流程或功能。所述计算机可以是通用计算机、专用计算机、计算机网络、或者其他可编程装置。所述计算机指令可以存储在计算机可读存储介质中,或者从一个计算机可读存储介质向另一个计算机可读存储介质传输,例如,所述计算机指令可以从一个网站站点、计算机、服务器或数据中心通过有线(例如同轴电缆、光纤、数字用户线(DSL))或无线(例如红外、无线、微波等)方式向另一个网站站点、计算机、服务器或数据中心进行传输。所述计算机可读存储介质可以是计算机能够存取的任何可用介质或者是包含一个或多个可用介质集成的服务器、数据中心等数据存储设备。所述可用介质可以是磁性介质,(例如,软盘、硬盘、磁带)、光介质(例如,DVD)、或者半导体介质(例如固态硬盘Solid State Disk(SSD))等。

需要说明的是,在本文中,诸如“第一”和“第二”等之类的关系术语仅仅用来将一个实体或者操作与另一个实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存在任何这种实际的关系或者顺序。而且,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、物品或者设备中还存在另外的相同要素。

应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。在描述中,使用用于表示元件的诸如“模块”、“部件”或“单元”的后缀仅为了有利于本发明的说明,其本身没有特定的意义。因此,“模块”、“部件”或“单元”可以混合地使用。

以上所述仅是本发明的具体实施方式,使本领域技术人员能够理解或实现本发明。对这些实施例的多种修改对本领域的技术人员来说将是显而易见的,本文中所定义的一般原理可以在不脱离本发明的精神或范围的情况下,在其它实施例中实现。因此,本发明将不会被限制于本文所示的这些实施例,而是要符合与本文所申请的原理和新颖特点相一致的最宽的范围。

技术分类

06120115959309