CN104536773B - 基于内存扫描的嵌入式软件动态内存回收方法 - Google Patents
基于内存扫描的嵌入式软件动态内存回收方法 Download PDFInfo
- Publication number
- CN104536773B CN104536773B CN201510054542.1A CN201510054542A CN104536773B CN 104536773 B CN104536773 B CN 104536773B CN 201510054542 A CN201510054542 A CN 201510054542A CN 104536773 B CN104536773 B CN 104536773B
- Authority
- CN
- China
- Prior art keywords
- memory
- access
- blocks
- internal memory
- memory block
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
Landscapes
- Memory System (AREA)
- Stored Programmes (AREA)
Abstract
本发明涉及内存管理技术领域,尤其涉及一种基于内存扫描的嵌入式软件动态内存回收方法。包括步骤:(1)确定软件程序能访问到的内存区域;(2)接管程序/系统动态内存的分配和释放过程;(3)满足触发扫描的条件时,扫描可访问的内存区域,并将可访问内存块加入可访问内存块集合;(4)释放所有不在可访问内存块集合中的动态内存块;(5)继续执行步骤(3)、(4),直到收到退出指令后停止。本发明使用内存扫描方法无需改变原有的程序实现机制,因此不会带来性能的损失。同时,无需增加额外开发工作量,还可以和所有第三方库兼容。
Description
技术领域
本发明涉及内存管理技术领域,尤其涉及一种基于内存扫描的嵌入式软件动态内存回收方法。
背景技术
在软件开发过程中,内存管理是一个复杂的问题,对于功能复杂的程序而言,使用动态分配是不可避免的。因为多个功能所使用的内存数量一直会变化,某些情况下会使用较多的内存,另一些情况下使用较少的内存。一般动态分配的内存都由操作系统来管理,从一个叫做“堆(Heap)”的内存区域分配,当程序调用接口函数申请内存时,操作系统从堆空间中找到一块空闲区域,分配给程序;当程序释放内存时,操作系统再把内存块标记为空闲,可以供重新分配。对于设计不良的程序,其中可能会有之前分配的动态内存已经不用,但是没有释放的情况,这就是所谓的“内存泄漏(Memory Leak)”。一旦长期运行的程序中存在内存泄漏,堆内存不断被分配出去而不被释放,久而久之,可用内存越来越少,最终,再也无法成功分配出内存,导致功能失效,甚至装置崩溃。
内存回收就是将程序中已经不使用但是又没释放的动态内存块自动释放的过程。在内存回收后,不被使用的内存块被归还到堆中,可再次被动态分配,从而避免内存泄漏情况的出现。
目前在嵌入式系统中进行内存回收可用的方案包括:
1)使用支持内存回收的语言开发
目前,支持垃圾回收的语言包括JAVA、.NET等,或者Python等脚本语言。它们的特点是程序并不被编译成特定CPU的机器码,而是被编译成一种中间代码,然后由一段解释程序在运行时动态将中间代码翻译为机器码执行,这段解释程序被称作虚拟机(VM)。在程序运行过程中,虚拟机会实时管理内存分配和释放的情况,对于已经不引用的内存,就自动释放掉,这样就避免了内存泄漏的情况。不同的语言使用的内存回收策略也有所不同。
使用支持垃圾回收的语言开发,就可以在很大程度上降低内存管理的复杂性,开发者仅需在需要分配内存的时候分配即可,而将释放内存的过程交给语言本身的内存回收机制完成,从而避免了内存泄漏的情况。
这种方式的缺点在于:解释执行的语言在性能上比编译为机器代码执行的语言要低,加之嵌入式设备硬件性能有限,在实时性要求比较高的场合并不适用。
2)使用智能指针管理内存
在C++中,由于语言本身没有提供内存回收机制,为了降低内存管理的复杂度,引入了“智能指针”的概念。智能指针的概念是和“裸指针”相对应的,裸指针就是传统的指针,表示的是内存的地址;而智能指针则是经过封装的对象,它除了保存了内存地址外,还保存了一些诸如引用计数之类的附加信息。智能指针的实现使用了C++语言的特性,在智能指针析构时,会自动修改其所指向的内存块的引用计数,当引用计数变为0时,就将指向的内存块释放掉。其由于智能指针重载了传统指针具备的几种运算符(如*、->等),因此在编程中基本无需特别关心智能指针的操作,只需按照传统指针使用即可。
目前在常用的C++开发框架中均提供了智能指针实现,例如boost,QT等。
这种机制的缺点是引入了自定义的内存管理机制,增加了开发时的工作量。无法管理在第三方库中分配的动态内存,难免出现内存泄漏。此外,智能指针的实现使用了C++的语言特性,在某些仅能使用C语言的场合无法使用。
3)使用基于所有者的对象树管理机制
由于在实际使用的情况中,程序中动态分配的对象一般在生存期上有依存关系,子对象的生存期一般不会超过父对象的生存期,所以将程序动态分配的对象按依存关系组织成一个对象树。当父对象析构时,将父对象的所有子对象全部释放。这样,应用程序就只需管理好处于顶层对象的生存期即可,大大降低了由于程序中的失误造成内存泄漏的可能性。
这种机制的缺点与方法2)中相同,由于引入了自定义的管理机制,因此无法用来管理第三方库中分配的动态内存。
发明内容
针对上述方案存在的程序执行性能低、软件开发工作量大和无法管理第三方代码库分配的动态内存等问题,本发明提供了一种基于内存扫描的嵌入式软件动态内存回收方法,在不额外增加开发工作量的前提下,实现动态内存的有效回收,并能兼容任何第三方库。
为达到上述目的,本发明采用了内存扫描的方式。在C/C++语言中,对内存的访问都是通过指针进行的。所谓指针,就是某个数据或对象在内存中的地址值。每个动态分配的内存块也都有自己的地址,当需要访问内存块中的数据时,也是通过指向该内存块的指针来访问。
在应用程序中,动态分配内存后,会将分配到的内存块的地址保存下来,以备后续操作中用来访问内存块中的数据。因此,如果我们通过对程序能访问到的整块内存进行扫描,找不到有指向某个动态内存块的指针值,则可以断定,这块动态内存块已经无法访问,可以将其释放。
结合上述构思,本发明采用的具体技术方案如下:
基于内存扫描的嵌入式软件动态内存回收方法,包括以下步骤:
(1)确定软件程序能访问到的内存区域;
(2)接管程序/系统动态内存的分配和释放过程,分配动态内存时,将分配到的动态内存块加入动态内存块集合中;释放内存时,将其从动态内存块集合中移除;
(3)满足触发扫描条件时,开始扫描可访问的内存区域,寻找内存地址范围在动态内存块集合的内存块范围中但未标记为可访问的内存块,将其标记为可访问并加入可访问内存块集合;再循环扫描可访问内存块集合中的内存块对应区域,寻找并继续向可访问内存块集合中增加符合上述条件的内存块,直至可访问内存块集合中的内存块全被扫描过;
(4)将动态内存块集合与可访问内存块集合比较,释放所有不在可访问内存块集合中的动态内存块;
(5)继续执行步骤(3)、(4),直到收到退出指令后停止。
经过上述扫描过程后,凡在可访问内存块集合中的动态内存块,均为在程序中有可能被引用的内存块,而不在可访问内存块集合中的动态内存块,就是不会被访问的内存块,由于该内存块未被释放,说明该内存块在程序中没有显示被释放,则将其自动释放掉。
单独建立一个线程定时对整块内存进行上述扫描,将无法访问的内存块释放掉,则在应用程序中可以无需关心动态内存的释放,显著降低开发工作量。同时,如果程序中引用了第三方的代码库,也可以将第三方代码库中分配的内存块也纳入管理,同时,第三方代码库中原有的分配释放机制也无需改动,即便第三方库中有内存泄漏的缺陷,在内存扫描过程中,也可以检测到无法访问到的内存块并自动释放。
进一步,步骤(2)和步骤(3)之间还包括以下步骤:等待触发内存扫描的条件,满足触发条件前,内存扫描任务处于挂起状态。所述触发条件为根据嵌入式系统整体资源情况和/或CPU性能确定的扫描频率。内存扫描的频率可根据嵌入式系统整体的资源情况来确定,在内存比较宽裕的系统上,可以使用较低的扫描频率;在内存紧张的系统上可以使用较高的扫描频率;如果CPU性能较低,为了减少内存扫描任务对其它功能的影响,可以不定时扫描,而在可用内存不足时开启扫描。
进一步,步骤(1)中软件程序能访问到的内存区域包括堆、栈和静态内存区域。
优选的,步骤(2)接管程序动态内存的分配和释放过程采用宏定义方式,将程序中调用的内存分配和释放函数重定向到自定义的函数中。这种方式仅仅在包含了此宏定义的代码中有效,对系统库及引用的第三方库无影响。
优选的,步骤(2)接管系统动态内存的分配和释放过程通过修改系统中内存分配和释放的机器代码,将执行流跳转到自定义的函数中。这种方式可以接管应用程序、系统库及第三方库中所有的内存分配和释放过程。
步骤(3)的具体步骤为:
(3-1)扫描静态内存区域:对静态内存区域的每个以指针类型大小对齐的内存地址,均当做指针读出其取值,如果取值范围在动态内存块集合中的某一内存块范围内,且该内存块未被标记为可访问,则将该内存块标记为可访问,并将该内存块加入可访问内存块集合;
(3-2)扫描栈内存区域:对栈内存区域的每个以指针类型大小对齐的内存地址,均当做指针读出其取值,如果取值范围在动态内存块集合中的某一内存块范围内,且该内存块未被标记为可访问,则将该内存块标记为可访问,并将该内存块加入可访问内存块集合;
(3-3)扫描可访问内存块集合中的内存块:对可访问内存块集合中的内存块指向的内存区域,对每个以指针类型大小对齐的内存地址均当做指针读出其取值,如果取值范围在动态内存块集合中的某一内存块范围内,且该内存块未被标记为可访问,则将该内存块标记为可访问,并将该内存块加入可访问内存块集合;
循环执行(3-3),直到可访问内存块集合中的内存块全部被扫描过为止。
本发明的优点如下:
(1)对系统整体性能影响小。
相对于采用JAVA、C#等解释型编程语言的方法,使用内存扫描方法无需改变原有的程序实现机制,因此不会带来性能的损失。而增加的内存扫描和释放任务(线程),其频率及扫描时机均可根据装置硬件性能及应用程序的需要酌情配置,因此对性能的影响可以忽略不计。
(2)无需增加额外开发工作量。
相对于智能指针和对象树的管理方式,内存扫描的方法只需在程序开始时初始化内存扫描任务即可,程序功能的实现过程无需做任何更改即可实现对内存泄漏的预防。
(3)可兼容任何第三方库。
该方法没有改变指针的使用方式,因此可以和所有第三方库兼容。如果使用修改机器代码的接管方式,还可以对第三方库中分配的动态内存进行管理,第三方库中如果有内存泄漏,也可以自动释放。
附图说明
图1是本发明实施方式的流程图。
具体实施方式
基于内存扫描的嵌入式软件动态内存回收方法,包括以下步骤:
(1)获取软件程序能访问到的内存区域范围。
软件程序能访问到的内存区域包括堆、栈和静态内存区域。
(2)接管程序/系统动态内存的分配和释放过程。
接管程序动态内存的分配和释放过程时可采用宏定义方式,将程序中调用的内存分配和释放函数重定向到自定义的函数中;而接管系统动态内存的分配和释放过程时可通过修改系统中内存分配和释放的机器代码,将执行流跳转到自定义的函数中。以上两种方式动态内存的分配和释放过程,在分配动态内存时,将分配到的动态内存块加入动态内存块集合中;释放内存时,将其从动态内存块集合中移除。
(3)等待触发内存扫描的条件。
在满足触发条件前,内存扫描任务处于挂起状态。若满足触发条件,进行下一步的扫描操作。
(4)扫描可访问的内存区域。
(4-1)、扫描静态内存区域。
对静态内存区域的每个以指针类型大小对齐的内存地址,均当做指针读出其取值,如果取值范围在动态内存块集合中的某一内存块范围内,且该内存块未被标记为可访问,则将该内存块标记为可访问,并将该内存块加入可访问内存块集合。
(4-2)扫描栈内存区域。
对栈内存区域的每个以指针类型大小对齐的内存地址,均当做指针读出其取值,如果取值范围在动态内存块集合中的某一内存块范围内,且该内存块未被标记为可访问,则将该内存块标记为可访问,并将该内存块加入可访问内存块集合。
(4-3)扫描可访问内存块集合中的内存块。
对可访问内存块集合中的内存块指向的内存区域,对每个以指针大小对齐的内存地址均当做指针读出其取值,如果取值范围在动态内存块集合中的某一内存块范围内,且该内存块未被标记为可访问,则将该内存块标记为可访问,并将该内存块加入可访问内存块集合。由于每个可访问内存块区域还存储有一些内存地址,继续对每个可访问内存块进行扫描判断,将符合上述条件的内存块加入可访问内存块集合中,而已存在于可访问内存块中的内存块则忽略。
循环执行(4-3)操作,直到可访问内存块集合中的内存块全部都被扫描过为止。这样所有指针值在动态内存块集合中但不在可访问内存块集合中的内存块均被找出,加入可访问内存块集合中,可访问内存块集合中的动态内存块均能在内存区找到指针值,能通过指针访问。而存在于动态内存块集合中却不在可访问内存块集合中的动态内存块,则没法通过指针访问,应该被释放,即进行下一步释放操作。
(5)释放所有不在可访问内存块集合的动态内存块。
(6)继续转到步骤(3)进行内存回收进程,直到使用此内存回收方法的程序退出为止,在程序退出前应先置上退出标志通知此进程先退出。若使用此方法管理整个系统的内存分配和回收,则应等到整个系统关闭时退出。
Claims (7)
1.基于内存扫描的嵌入式软件动态内存回收方法,其特征在于包括以下步骤:
(1)确定软件程序能访问到的内存区域;
(2)接管程序/系统动态内存的分配和释放过程,分配动态内存时,将分配到的动态内存块加入动态内存块集合中;释放内存时,将其从动态内存块集合中移除;
(3)满足触发扫描条件时,开始扫描可访问的内存区域,寻找内存地址范围在动态内存块集合的内存块范围中但未标记为可访问的内存块,将其标记为可访问并加入可访问内存块集合;再循环扫描可访问内存块集合中的内存块对应区域,寻找并继续向可访问内存块集合中增加符合上述条件的内存块,直至可访问内存块集合中的内存块全被扫描过;
(4)将动态内存块集合与可访问内存块集合比较,释放所有不在可访问内存块集合中的动态内存块;
(5)继续执行步骤(3)、(4),直到收到退出指令后停止。
2.根据权利要求1所述的基于内存扫描的嵌入式软件动态内存回收方法,其特征在于:步骤(2)和步骤(3)之间还包括以下步骤:等待触发内存扫描的条件,满足触发条件前,内存扫描任务处于挂起状态。
3.根据权利要求2所述的基于内存扫描的嵌入式软件动态内存回收方法,其特征在于:所述触发条件为根据嵌入式系统整体资源情况和/或CPU性能确定的扫描频率。
4.根据权利要求1或2或3所述的基于内存扫描的嵌入式软件动态内存回收方法,其特征在于:步骤(1)中软件程序能访问到的内存区域包括堆、栈和静态内存区域。
5.根据权利要求1所述的基于内存扫描的嵌入式软件动态内存回收方法,其特征在于:步骤(2)接管程序动态内存的分配和释放过程采用宏定义方式,将程序中调用的内存分配和释放函数重定向到自定义的函数中。
6.根据权利要求1所述的基于内存扫描的嵌入式软件动态内存回收方法,其特征在于:步骤(2)接管系统动态内存的分配和释放过程通过修改系统中内存分配和释放的机器代码,将执行流跳转到自定义的函数中。
7.根据权利要求4所述的基于内存扫描的嵌入式软件动态内存回收方法,其特征在于:步骤(3)的具体步骤为:
(3-1)扫描静态内存区域:对静态内存区域的每个以指针类型大小对齐的内存地址,均当做指针读出其取值,如果取值范围在动态内存块集合中的某一内存块范围内,且该内存块未被标记为可访问,则将该内存块标记为可访问,并将该内存块加入可访问内存块集合;
(3-2)扫描栈内存区域:对栈内存区域的每个以指针类型大小对齐的内存地址,均当做指针读出其取值,如果取值范围在动态内存块集合中的某一内存块范围内,且该内存块未被标记为可访问,则将该内存块标记为可访问,并将该内存块加入可访问内存块集合;
(3-3)扫描可访问内存块集合中的内存块:对可访问内存块集合中的内存块指向的内存区域,对每个以指针类型大小对齐的内存地址均当做指针读出其取值,如果取值范围在动态内存块集合中的某一内存块范围内,且该内存块未被标记为可访问,则将该内存块标记为可访问,并将该内存块加入可访问内存块集合;循环执行(3-3),直到可访问内存块集合中的内存块全部被扫描过为止。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201510054542.1A CN104536773B (zh) | 2015-02-03 | 2015-02-03 | 基于内存扫描的嵌入式软件动态内存回收方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201510054542.1A CN104536773B (zh) | 2015-02-03 | 2015-02-03 | 基于内存扫描的嵌入式软件动态内存回收方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN104536773A CN104536773A (zh) | 2015-04-22 |
CN104536773B true CN104536773B (zh) | 2017-11-21 |
Family
ID=52852305
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201510054542.1A Active CN104536773B (zh) | 2015-02-03 | 2015-02-03 | 基于内存扫描的嵌入式软件动态内存回收方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN104536773B (zh) |
Families Citing this family (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN105117410B (zh) * | 2015-07-28 | 2020-03-27 | 阿里巴巴集团控股有限公司 | 一种应用对象的创建方法及装置 |
KR20180076058A (ko) * | 2016-12-27 | 2018-07-05 | 에이치피프린팅코리아 주식회사 | 화상 형성 장치에서 실행되는 가상 머신의 동작 환경을 최적화하는 화상 형성 장치 및 방법 |
CN107247674B (zh) * | 2017-06-16 | 2020-07-31 | 深圳市万普拉斯科技有限公司 | 内存块类型处理方法、装置、电子设备及可读存储介质 |
JP6943091B2 (ja) * | 2017-09-06 | 2021-09-29 | コニカミノルタ株式会社 | 画像処理装置、画像処理システム及びプログラム |
CN111078540B (zh) * | 2019-11-29 | 2023-03-07 | 四川九洲空管科技有限责任公司 | 基于qt开发通用航空飞行服务软件内存异常检测定位方法 |
Citations (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN102103541A (zh) * | 2011-02-28 | 2011-06-22 | 中国人民解放军国防科学技术大学 | 防止内存泄露和内存多次释放的内核模块内存管理方法 |
Family Cites Families (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US6993540B2 (en) * | 2002-12-20 | 2006-01-31 | Intel Corporation | Prefetching memory objects into a shared cache during garbage collection with a three-finger Cheney scan in a multithreaded processing environment |
US20080140737A1 (en) * | 2006-12-08 | 2008-06-12 | Apple Computer, Inc. | Dynamic memory management |
-
2015
- 2015-02-03 CN CN201510054542.1A patent/CN104536773B/zh active Active
Patent Citations (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN102103541A (zh) * | 2011-02-28 | 2011-06-22 | 中国人民解放军国防科学技术大学 | 防止内存泄露和内存多次释放的内核模块内存管理方法 |
Also Published As
Publication number | Publication date |
---|---|
CN104536773A (zh) | 2015-04-22 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN104536773B (zh) | 基于内存扫描的嵌入式软件动态内存回收方法 | |
CN101971146B (zh) | 改进作为管理程序来宾而运行的虚拟机中内存使用情况的系统和方法 | |
US8650538B2 (en) | Meta garbage collection for functional code | |
CN102929785B (zh) | 在事务处理码内对存储器分配和解除分配的系统和方法 | |
US7882505B2 (en) | Method and apparatus for switching between per-thread and per-processor resource pools in multi-threaded programs | |
US8554807B2 (en) | Incremental class unloading in a region-based garbage collector | |
US20090307292A1 (en) | Dynamically changing a garbage collector in a managed runtime system | |
CN1514354A (zh) | 面向构件基于系统内核的进程池/线程池管理方法 | |
US7908454B2 (en) | Application-specific heap management | |
CN1961292A (zh) | 用于受管运行时环境的线程同步方法和装置 | |
CN1271524C (zh) | 一种静态内存管理方法 | |
US20100088675A1 (en) | System and method of using pooled thread-local character arrays | |
CN101421711A (zh) | 用于资源受限设备的虚拟执行系统 | |
CN1996258A (zh) | 一种动态内存池的实现方法 | |
CN101799773A (zh) | 并行计算的内存访问方法 | |
US20090150613A1 (en) | Memory management | |
US8881162B2 (en) | Apparatus and method for managing resources in containment framework environment | |
CN104077266B (zh) | 多内核操作系统实现方法和实现装置及系统 | |
JP2015519646A (ja) | マルチテナント型アプリケーション・ドメイン及びメモリの管理を伴う修正されたjvm | |
CN106484826A (zh) | 一种操作数据库的方法及装置 | |
JP2021530756A (ja) | ポーズレスなガベージ・コレクションのための活性化フレームを表す方法および装置 | |
US20020073404A1 (en) | Method and apparatus for storing long-lived objects in a virtual machine | |
CN102567220A (zh) | Cache存取的控制方法及装置 | |
US7334104B2 (en) | Satisfying memory allocation requests from memory pool or lookaside lists based on memory size requested to be allocated | |
CN1816802A (zh) | 用于准确的指针识别的处理器体系结构 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |