CN104536773A - 基于内存扫描的嵌入式软件动态内存回收方法 - Google Patents
基于内存扫描的嵌入式软件动态内存回收方法 Download PDFInfo
- Publication number
- CN104536773A CN104536773A CN201510054542.1A CN201510054542A CN104536773A CN 104536773 A CN104536773 A CN 104536773A CN 201510054542 A CN201510054542 A CN 201510054542A CN 104536773 A CN104536773 A CN 104536773A
- Authority
- CN
- China
- Prior art keywords
- memory
- memory block
- addressable
- dram
- region
- 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.)
- Granted
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.基于内存扫描的嵌入式软件动态内存回收方法,其特征在于包括以下步骤:
确定软件程序能访问到的内存区域;
接管程序/系统动态内存的分配和释放过程,分配动态内存时,将分配到的动态内存块加入动态内存块集合中;释放内存时,将其从动态内存块集合中移除;
满足触发扫描条件时,开始扫描可访问的内存区域,寻找内存地址范围在动态内存块集合的内存块范围中但未标记为可访问的内存块,将其标记为可访问并加入可访问内存块集合;再循环扫描可访问内存块集合中的内存块对应区域,寻找并继续向可访问内存块集合中增加符合上述条件的内存块,直至可访问内存块集合中的内存块全被扫描过;
将动态内存块集合与可访问内存块集合比较,释放所有不在可访问内存块集合中的动态内存块;
继续执行步骤(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 true CN104536773A (zh) | 2015-04-22 |
CN104536773B 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) |
Cited By (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN105117410A (zh) * | 2015-07-28 | 2015-12-02 | 阿里巴巴集团控股有限公司 | 一种应用对象的创建方法及装置 |
WO2018228340A1 (zh) * | 2017-06-16 | 2018-12-20 | 深圳市万普拉斯科技有限公司 | 内存块类型处理方法、装置、电子设备及可读存储介质 |
CN109462709A (zh) * | 2017-09-06 | 2019-03-12 | 柯尼卡美能达株式会社 | 图像处理装置、图像处理系统以及程序 |
CN109644223A (zh) * | 2016-12-27 | 2019-04-16 | 惠普打印机韩国有限公司 | 对虚拟机的操作环境进行优化 |
CN111078540A (zh) * | 2019-11-29 | 2020-04-28 | 四川九洲空管科技有限责任公司 | 基于qt开发通用航空飞行服务软件内存异常检测定位方法 |
Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US20040122876A1 (en) * | 2002-12-20 | 2004-06-24 | Hudson Richard L. | Execution of modified cheney scanning in a multithreaded processing environment |
US20080140737A1 (en) * | 2006-12-08 | 2008-06-12 | Apple Computer, Inc. | Dynamic memory management |
CN102103541A (zh) * | 2011-02-28 | 2011-06-22 | 中国人民解放军国防科学技术大学 | 防止内存泄露和内存多次释放的内核模块内存管理方法 |
-
2015
- 2015-02-03 CN CN201510054542.1A patent/CN104536773B/zh active Active
Patent Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US20040122876A1 (en) * | 2002-12-20 | 2004-06-24 | Hudson Richard L. | Execution of modified cheney scanning in a multithreaded processing environment |
US20080140737A1 (en) * | 2006-12-08 | 2008-06-12 | Apple Computer, Inc. | Dynamic memory management |
CN102103541A (zh) * | 2011-02-28 | 2011-06-22 | 中国人民解放军国防科学技术大学 | 防止内存泄露和内存多次释放的内核模块内存管理方法 |
Cited By (8)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN105117410A (zh) * | 2015-07-28 | 2015-12-02 | 阿里巴巴集团控股有限公司 | 一种应用对象的创建方法及装置 |
CN105117410B (zh) * | 2015-07-28 | 2020-03-27 | 阿里巴巴集团控股有限公司 | 一种应用对象的创建方法及装置 |
CN109644223A (zh) * | 2016-12-27 | 2019-04-16 | 惠普打印机韩国有限公司 | 对虚拟机的操作环境进行优化 |
WO2018228340A1 (zh) * | 2017-06-16 | 2018-12-20 | 深圳市万普拉斯科技有限公司 | 内存块类型处理方法、装置、电子设备及可读存储介质 |
US11137934B2 (en) | 2017-06-16 | 2021-10-05 | Oneplus Technology (Shenzhen) Co., Ltd. | Memory block type processing method applicable to electronic device electronic device and non-transitory computer readable storage medium |
CN109462709A (zh) * | 2017-09-06 | 2019-03-12 | 柯尼卡美能达株式会社 | 图像处理装置、图像处理系统以及程序 |
CN111078540A (zh) * | 2019-11-29 | 2020-04-28 | 四川九洲空管科技有限责任公司 | 基于qt开发通用航空飞行服务软件内存异常检测定位方法 |
CN111078540B (zh) * | 2019-11-29 | 2023-03-07 | 四川九洲空管科技有限责任公司 | 基于qt开发通用航空飞行服务软件内存异常检测定位方法 |
Also Published As
Publication number | Publication date |
---|---|
CN104536773B (zh) | 2017-11-21 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
JP5868429B2 (ja) | 領域に基づくガベージ・コレクタを用いてクラスを漸進的にアンロードするための方法、コンピュータ・プログラム製品、および装置 | |
CN104536773A (zh) | 基于内存扫描的嵌入式软件动态内存回收方法 | |
US8650538B2 (en) | Meta garbage collection for functional code | |
EP2175370B1 (en) | System and method of using pooled thread-local character arrays | |
CN101859279B (zh) | 一种内存分配、释放方法及装置 | |
US20060123423A1 (en) | Borrowing threads as a form of load balancing in a multiprocessor data processing system | |
US8074025B2 (en) | Method and system for copying live entities of source blocks identified by source list for selected destination block to selected destination block of memory heap | |
US20090307292A1 (en) | Dynamically changing a garbage collector in a managed runtime system | |
US9740716B2 (en) | System and method for dynamically selecting a garbage collection algorithm based on the contents of heap regions | |
US20150331682A1 (en) | Data splitting for recursive data structures | |
JP2015519646A (ja) | マルチテナント型アプリケーション・ドメイン及びメモリの管理を伴う修正されたjvm | |
CN111736913B (zh) | 类加载方法和装置 | |
JP2000242551A (ja) | メモリ管理のための方法および装置 | |
US20060101468A1 (en) | Cooperative threading in a managed code execution environment | |
WO2019105565A1 (en) | Systems for compiling and executing code within one or more virtual memory pages | |
US20080140979A1 (en) | Method of allocating stack in multi-threaded sensor operating system environment | |
CN101763308A (zh) | 在运行时对堆数据进行池分配的方法 | |
CN100549958C (zh) | 一种类文件装载方法和系统 | |
US11188460B2 (en) | Arena-based memory management | |
KR20080054324A (ko) | 멀티 쓰레드 기반 센서 운영체제 환경에서의 스택 할당방법 | |
US9250878B1 (en) | Function attribute for dynamic stack allocation | |
US20080034022A1 (en) | System and method for updating references when incrementally compacting a heap | |
Friedman et al. | Hash tables for embedded and real-time systems | |
CN109800086B (zh) | 一种优化编译器ram空间的方法 | |
Riegel et al. | Making object-based STM practical in unmanaged environments |
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 |