一种内存管理方法及系统
技术领域
本发明涉及一种计算机技术,特别是涉及一种内存管理方法及系统。
背景技术
内存越界是我们软件开发中经常遇到的一个问题。何谓内存访问越界,简单的说,你向系统申请了一块内存,在使用这块内存的时候,超出了你申请的范围。内存越界通常可能会造成如下后果:1,破坏堆中的内存分配信息数据,特别是动态分配的内存块的内存信息数据。2,破坏程序自己的其他对象的内存空间,这种破坏会影响程序执行的不正确性,当然也会诱发coredump,如破坏了指针数据。3,破坏了空闲内存块,很幸运,这样不会产生什么问题,但谁知道什么时候不幸会降临呢?所以有效的检测和快速的定位内存越界的机制就十分重要。另外对于无屏的嵌入式设备(如路由器,交换机等)由于没有屏幕显示错误,只有当调试人员连接串口或者telnet查看的时候才能看到设备的信息。现有的内存越界检测方案只描述了如何检测内存的上溢(上越界)和下溢(下越界),却并没有内存越界的定位方法和错误信息的记录机制,现有的简单检测方案在嵌入式设备上并不能解决内存越界的定位问题。
鉴于此,如何找到一种能够检测和定位内存越界问题的内存管理方案就成为了本领域技术人员亟待解决的问题。
发明内容
鉴于以上所述现有技术的缺点,本发明的目的在于提供一种内存管理方法及系统,用于解决现有技术中难以检测和定位内存越界的问题。
为实现上述目的及其他相关目的,本发明提供一种内存管理方法,所述内存管理方法包括:进行内存分配时,实际分配的内存包括头信息、需要分配的内存空间大小以及尾信息,所述头信息和尾信息中包括用于检测内存越界的信息,同时建立所分配内存的管理结构体,所述管理结构体中包括所分配内存的函数调用信息以及内存分配信息;进行内存释放时,根据所述内存的头信息和尾信息进行内存越界检测,当检测到发生内存越界时,保存所述内存的管理结构体,释放所述内存。
可选地,所述内存管理方法包括:进行内存释放时,根据所述内存的头信息和尾信息进行内存越界检测,当检测到未发生内存越界时,释放所述内存的管理结构体,释放所述内存。
可选地,所述头信息进行4字节对齐,包括三个4字节,第一个4字节存放内存标志信息,第二个4字节包括需要分配的内存空间大小,第三个4字节通过设定算法对所述内存空间大小计算得出;所述尾信息包括一个4字节数据,所述4字节存放的数据与头信息的第三个4字节内容相同。
可选地,所述内存越界检测的具体实现包括:通过所述设定算法对头信息的第二个4字节的数据计算得到的一个计算结果,将所述计算结果与所述头信息的第三个4字节数据进行比较,如果不一致,则发生内存下越界;将所述计算结果与所述尾信息的所述4字节数据进行比较,如果不一致,则发生内存上越界;当内存上越界与内存下越界都未发生时,表明未检测到发生内存越界,否则,表明检测到发生内存越界。
可选地,所述内存管理方法还包括:通过管理链表管理所述管理结构体,通过内存溢出链表保存发生内存越界的内存管理结构体。
可选地,所述内存管理方法还包括:在同一个共享库中实现所述内存分配和内存释放。
可选地,所述内存管理方法还包括:遍历所述内存溢出链表,输出所述内存溢出链表中的所有内存管理结构体的信息。
本发明提供一种内存管理系统,所述内存管理系统包括:内存分配模块,用于内存分配以及建立所分配内存的管理结构体,所述管理结构体中包括所分配内存的函数调用信息以及内存分配信息,将所述管理结构体加入到管理链表中;实际分配的内存包括头信息、需要分配的内存空间大小以及尾信息,所述头信息和尾信息中包括用于检测内存越界的信息;内存释放模块,用于内存释放以及越界管理,根据所述内存的头信息和尾信息进行内存越界检测,当检测到发生内存越界时,将所述内存对应的管理结构体从所述管理链表中移除,并将所述内存对应的管理结构体加入到内存溢出链表中,释放所述内存。
可选地,所述内存释放模块还用于:根据所述内存的头信息和尾信息进行内存越界检测,当检测到未发生内存越界时,将所述内存对应的管理结构体从所述管理链表中移除并释放所述管理结构体,释放所述内存。
可选地,所述内存溢出链表节点数目设有上限,当所述内存溢出链表的节点数目达到上限后,对所述内存溢出链表进行先入先出管理。
可选地,所述内存分配模块以及内存释放模块在同一个共享库中实现。
可选地,所述头信息进行4字节对齐,包括三个4字节,第一个4字节存放内存标志信息,第二个4字节包括需要分配的内存空间大小,第三个4字节通过设定算法对所述内存空间大小计算得出;所述尾信息包括一个4字节数据,所述4字节存放的数据与头信息的第三个4字节内容相同。
可选地,所述内存越界检测的具体实现包括:通过所述设定算法对头信息的第二个4字节的数据计算得到的一个计算结果,将所述计算结果与所述头信息的第三个4字节数据进行比较,如果不一致,则发生内存下越界;将所述计算结果与所述尾信息的所述4字节数据进行比较,如果不一致,则发生内存上越界;当内存上越界与内存下越界都未发生时,表明未检测到发生内存越界,否则,表明检测到发生内存越界。
可选地,所述内存分配信息包括所分配内存的起始地址、内存大小。
可选地,所述内存管理系统还包括内存越界信息输出模块,用于遍历所述内存溢出链表,输出所述内存溢出链表中的所有内存管理结构体的信息。
如上所述,本发明的一种内存管理方法及系统,具有以下有益效果:集内存越界的检测、定位和记录为一体,能快速的检测定位内存越界问题,并且将问题进行记录,方便开发人员的调试。同时由于通过共享库的方式完成本发明的方案,所以可以让链接了共享库的进程在其各自的内存空间内维护着本进程的内存溢出链表,即可以针对某一个进程单独调试,而不需要打印出所有进程的内存溢出信息。另外使用共享库的另一个优点在于可以简单的通过在共享库中的宏来打开和关闭所有进程的内存管理功能,因为上述内存管理功能都属于调试信息,往往只在开发版本中加入,而在发布版本中需要去除所有的调试信息。
附图说明
图1显示为本发明的内存管理方法的一实施例的流程示意图。
图2显示为本发明的内存管理方法的一实施例的分配流程示意图。
图3显示为本发明的内存管理方法的一实施例的释放流程示意图。
图4显示为本发明的内存管理方法的一实施例的内存溢出链表管理流程示意图。
图5显示为本发明的内存管理系统的一实施例的模块示意图。
元件标号说明
1内存管理系统
11内存分配模块
12内存释放模块
S1~S2步骤
具体实施方式
以下通过特定的具体实例说明本发明的实施方式,本领域技术人员可由本说明书所揭露的内容轻易地了解本发明的其他优点与功效。本发明还可以通过另外不同的具体实施方式加以实施或应用,本说明书中的各项细节也可以基于不同观点与应用,在没有背离本发明的精神下进行各种修饰或改变。
需要说明的是,本实施例中所提供的图示仅以示意方式说明本发明的基本构想,遂图式中仅显示与本发明中有关的组件而非按照实际实施时的组件数目、形状及尺寸绘制,其实际实施时各组件的型态、数量及比例可为一种随意的改变,且其组件布局型态也可能更为复杂。
本发明提供一种内存管理方法。在一个实施例中,如图1所示,所述内存管理方法包括:
步骤S1,进行内存分配时,实际分配的内存包括头信息、需要分配的内存空间大小以及尾信息,所述头信息和尾信息中包括用于检测内存越界的信息,同时建立所分配内存的管理结构体,所述管理结构体中包括所分配内存的函数调用信息以及内存分配信息。在一个实施例中,所述内存分配信息包括所分配内存的起始地址、内存大小。所述头信息进行4字节对齐,包括三个4字节(共12个字节),第一个4字节存放内存标志信息,第二个4字节包括需要分配的内存空间大小,第三个4字节通过设定算法对所述内存空间大小计算得出;所述尾信息包括一个4字节数据,所述4字节存放的数据与头信息的第三个4字节内容相同。这种分配方式下,每个分配的内存管理头尾的计算得出的标志(头信息的第三个4字节以及尾信息的4个字节)都不一样,都是结合内存大小这个参数通过算法算出,在这种算法下只有极小的概率出现溢出内容与标志相同的现象。在一个实施例中,通过管理链表管理所述管理结构体。内存管理结构体中保存函数调用信息(函数调用堆栈)。当检测到内存越界时,开发人员只要打印出这个函数调用堆栈,就可以找到是什么地方调用了该内存分配,而内存越界肯定是出现在使用这块内存的时候。这样就可以快速的定位问题。
步骤S2,进行内存释放时,根据所述内存的头信息和尾信息进行内存越界检测,当检测到发生内存越界时,保存所述内存的管理结构体,释放所述内存。在一个实施例中,所述内存管理方法包括:进行内存释放时,根据所述内存的头信息和尾信息进行内存越界检测,当检测到未发生内存越界时,释放所述内存的管理结构体,释放所述内存。在一个实施例中,所述内存越界检测的具体实现包括:通过所述设定算法对头信息的第二个4字节的数据(需要分配的内存空间大小)计算得到的一个计算结果,将所述计算结果与所述头信息的第三个4字节数据进行比较,如果不一致,则发生内存下越界;将所述计算结果与所述尾信息的所述4字节数据进行比较,如果不一致,则发生内存上越界;当内存上越界与内存下越界都未发生时,表明未检测到发生内存越界,否则,表明检测到发生内存越界。在一个实施例中,通过内存溢出链表保存发生内存越界的内存管理结构体。通过创建内存溢出链表,将所有出现内存越界的内存管理结构体都保存在这个链表上,从而对内存越界进行记录和保存,这尤其适合不能实时观察系统运行状态的嵌入式系统。
在一个实施例中,所述内存管理方法还包括:在同一个共享库中实现所述内存分配和内存释放。在这种情况下,内存分配与内存释放都是通过共享库的方式完成的,所以只要是链接了共享库的进程在其各自的内存空间内都维护着本进程的内存溢出链表,这样可以针对某一个进程单独调试,而不需要打印出所有进程的内存溢出信息。另外使用共享库的另一个优点在于可以简单的通过在共享库中的宏来打开和关闭所有进程的内存管理功能,因为上述内存管理功能都属于调试信息,往往只在开发版本中加入,而在发布版本中需要去除所有的调试信息。在一个实施例中,所述内存管理方法还包括:遍历所述内存溢出链表,输出所述内存溢出链表中的所有内存管理结构体的信息。当链接了共享库的进程收到外部的指定命令(消息,信号等),可以调用读取记录的接口,此接口遍历内存溢出链表,将链表中的信息(分配内存的大小,函数调用堆栈)统一输出到串口上。当进程收到指定清理命令后,可以统一删除释放内存溢出链表中的所有节点。本技术方案是集内存溢出的检测、定位和记录为一体的内存管理方法。
在一个实施例中,如图2所示,所述内存分配的流程如下:开始内存分配时,首先算出实际分配的内存大小,并按照实际分配大小分配内存。在一个实施例中,获得需要分配的内存大小后首先进行4字节对齐,然后再加上管理头和尾的大小后,才是真正需要分配的内存大小。即实际分配的内存大小=需要分配的内存大小+头信息的大小+尾信息的大小。当内存分配成功后,处理管理头(头信息)与管理尾(尾信息);分配失败则结束,返回空指针。在一个实施例中,管理头信息包括12字节,尾信息包括8字节。其中,管理头信息第一个4字节存放分配内存的标志信息,第二个4字节保存分配内存的大小,第三个4字节由第二个4字节通过一个算法算出,用于保证管理头的信息完整性和内存下溢(内存下越界)的检测。管理尾的8字节分为两个四字节,每个四字节也存放和管理头第三个4字节相同的标识,用于内存上溢((内存下越界))的检测。然后创建内存管理结构体。在一个实施例中,内存管理结构体包含如下信息:分配的内存地址,内存大小,函数调用堆栈(函数调用信息)以及内存溢出的标识。如果创建内存管理结构体失败,则结束,返回空指针。否则,内存管理结构体构建好后,填写结构体信息,加入管理链表。此管理结构体是内存越界问题定位和记录的核心。在一个实施例中,如图3所示,所述内存释放的流程如下:首先遍历管理链表寻找与待释放的内存相对应的内存管理结构体。然后,检验内存的管理头(头信息)与管理尾(尾信息),首先检查管理头,管理头的第二个四字节内容必须和内存大小相同,然后通过内存大小算出第三个四字节的内容,并进行对比,如果不一致,则说明该内容被损坏,可以确定发生了内存下溢(内存下越界)。然后再查看管理尾,然后通过内存大小算出尾信息的内容,并与尾信息进行对比,如果不一致,如果管理尾被损坏,可以确定发生了内存上溢(内存下越界)。如果分配的内存未出现越界问题,则释放管理结构体,释放分配的内存。如果出现了内存越界,则将内存溢出标志位改变,并将这个管理结构体移出管理链表并添加到内存溢出链表(也可称为错误管理链表)上,然后释放分配的内存。在一个实施例中,如图4所示,所述内存溢出链表的节点数目设有上限,当所述内存溢出链表的节点数目达到上限后,对所述内存溢出链表进行先入先出管理。当有新的发生内存越界的管理结构体需要插入到内存溢出链表时,首先检测链表的节点数目(链表长度)是否已达到上限,如果未达到上限,则直接将待插入的管理结构体插入链表头,链表长度加1。如果链表的节点数目(链表长度)已达到上限,则移出链表尾节点(管理结构体),将待插入的管理结构体的内容替换所移出的链表尾节点的内容,将替换过结构体内容的链表尾节点重新插入链表头。或者移出链表尾节点(管理结构体)并将待插入的管理结构体插入到链表头。
本发明提供一种内存管理系统。所述内存管理系统可以采用如上所述的内存管理方法进行内存管理。在一个实施例中,如图5所示,所述内存管理系统包括内存分配模块11以及内存释放模块12。其中:
内存分配模块11用于内存分配以及建立所分配内存的管理结构体,所述管理结构体中包括所分配内存的函数调用信息以及内存分配信息,将所述管理结构体加入到管理链表中;实际分配的内存包括头信息、需要分配的内存空间大小以及尾信息,所述头信息和尾信息中包括用于检测内存越界的信息。在一个实施例中,所述内存分配信息包括所分配内存的起始地址、内存大小。所述头信息进行4字节对齐,包括三个4字节(共12个字节),第一个4字节存放内存标志信息,第二个4字节包括需要分配的内存空间大小,第三个4字节通过设定算法对所述内存空间大小计算得出;所述尾信息包括一个4字节数据,所述4字节存放的数据与头信息的第三个4字节内容相同。这种分配方式下,每个分配的内存管理头尾的计算得出的标志(头信息的第三个4字节以及尾信息的4个字节)都不一样,都是结合内存大小这个参数通过算法算出,在这种算法下只有极小的概率出现溢出内容与标志相同的现象。内存管理结构体中保存函数调用信息(函数调用堆栈)。当检测到内存越界时,开发人员只要打印出这个函数调用堆栈,就可以找到是什么地方调用了该内存分配,而内存越界肯定是出现在使用这块内存的时候。这样就可以快速的定位问题。
内存释放模块12与内存分配模块11相连,用于内存释放以及越界管理,根据所述内存的头信息和尾信息进行内存越界检测,当检测到发生内存越界时,将所述内存对应的管理结构体从所述管理链表中移除,并将所述内存对应的管理结构体加入到内存溢出链表中,释放所述内存。在一个实施例中,所述内存越界检测的具体实现包括:通过所述设定算法对头信息的第二个4字节的数据(需要分配的内存空间大小)计算得到的一个计算结果,将所述计算结果与所述头信息的第三个4字节数据进行比较,如果不一致,则发生内存下越界;将所述计算结果与所述尾信息的所述4字节数据进行比较,如果不一致,则发生内存上越界;当内存上越界与内存下越界都未发生时,表明未检测到发生内存越界,否则,表明检测到发生内存越界。在一个实施例中,通过内存溢出链表保存发生内存越界的内存管理结构体。通过创建内存溢出链表,将所有出现内存越界的内存管理结构体都保存在这个链表上,从而对内存越界进行记录和保存,这尤其适合不能实时观察系统运行状态的嵌入式系统。在一个实施例中,所述内存溢出链表的节点数目设有上限,当所述内存溢出链表的节点数目达到上限后,对所述内存溢出链表进行先入先出管理。当有新的发生内存越界的管理结构体需要插入到内存溢出链表时,首先检测链表的节点数目(链表长度)是否已达到上限,如果未达到上限,则直接将待插入的管理结构体插入链表头,链表长度加1。如果链表的节点数目(链表长度)已达到上限,则移出链表尾节点(管理结构体),并将待插入的管理结构体插入到链表头。或者,在链表的节点数目(链表长度)达到上限的时候,移出链表尾节点,并且将移出的链表尾节点(管理结构体)的内容替换为当前新的内容,然后再插入到链表头。这样做的好处在于可以省去申请新结构体和释放旧结构体的时间。
在一个实施例中,所述内存管理系统1在同一个共享库中实现所述内存分配模块11和内存释放模块12。在这种情况下,内存分配与内存释放都是通过共享库的方式完成的,所以只要是链接了共享库的进程在其各自的内存空间内都维护着本进程的内存溢出链表,这样可以针对某一个进程单独调试,而不需要打印出所有进程的内存溢出信息。另外使用共享库的另一个优点在于可以简单的通过在共享库中的宏来打开和关闭所有进程的内存管理功能,因为上述内存管理功能都属于调试信息,往往只在开发版本中加入,而在发布版本中需要去除所有的调试信息。
在一个实施例中,所述内存管理系统1还包括内存越界信息输出模块,用于遍历所述内存溢出链表,输出所述内存溢出链表中的所有内存管理结构体的信息。当链接了共享库的进程收到外部的指定命令(消息,信号等),可以调用读取记录的接口,此接口遍历内存溢出链表,将链表中的信息(分配内存的大小,函数调用堆栈)统一输出到串口上。当进程收到指定清理命令后,可以统一删除释放内存溢出链表中的所有节点。本技术方案是集内存溢出的检测、定位和记录为一体的内存管理方法。
综上所述,本发明的一种内存管理方法及系统集内存越界的检测、定位和记录为一体,能快速的检测定位内存越界问题,并且将问题进行记录,方便开发人员的调试。同时由于通过共享库的方式完成本发明的方案,所以可以让链接了共享库的进程在其各自的内存空间内维护着本进程的内存溢出链表,即可以针对某一个进程单独调试,而不需要打印出所有进程的内存溢出信息。另外使用共享库的另一个优点在于可以简单的通过在共享库中的宏来打开和关闭所有进程的内存管理功能,因为上述内存管理功能都属于调试信息,往往只在开发版本中加入,而在发布版本中需要去除所有的调试信息。所以,本发明有效克服了现有技术中的种种缺点而具高度产业利用价值。
上述实施例仅例示性说明本发明的原理及其功效,而非用于限制本发明。任何熟悉此技术的人士皆可在不违背本发明的精神及范畴下,对上述实施例进行修饰或改变。因此,举凡所属技术领域中具有通常知识者在未脱离本发明所揭示的精神与技术思想下所完成的一切等效修饰或改变,仍应由本发明的权利要求所涵盖。