嵌入式实时操作系统的设计与开发 (内存管理机制简介)

从1946年的第一台计算机到当代最先进的超级计算机都没有跳出冯.诺依曼体系结构,即由运算器、控制器、存储器、输入/输出设备为基础的计算机体系结构。

计算机运行过程中,把要执行的程序和处理的数据首先存入存储器,计算机指向程序时,将按顺序从主存储器中取出指令并执行。
这些指令就是抽象出来的基本运算单元,如加/减法、读写存储器等。

后来随着中央处理器的飞速发展,存储器的读取速度限制了整体的效率,于是就出现了内存与外存的分类。

  • 低速但廉价的存储设备被用作外存,用于提供大量的空间。
  • 高速但昂贵的存储设备被用作内存,用于和中央处理器交互和暂存少量数据。
  • 高速缓存(Cache),解决主内存速度跟不上中央处理器,从广义上讲,高速缓存也属于内存。

内存管理,就是把物理的存储资源用一定的规则和手段管理起来,以供给操作系统和应用程序使用。主要的操作就两种:内存的分配和内存的回收。

内存的利用率、分配回收的效率和稳定性就成了评价内存管理模块的主要依据。

内存管理的内存分配方式又包括静态和动态两种。

  • 静态分配的方式很简单,但必须事先预知程序的运行的全貌(代码大小、数据大小等),这样的系统必然缺乏灵活性。
  • 动态分配的方式比较灵活,也是常见的分配方式,但动态分配必然会耗费一些内存管理过程中额外的空间和时间开销。
    所以在内存特别小、对实时性要求特别高的情况下还是会采用静态分配的方法。

malloc()、free()函数,当要分配6B的内存时,其实操作系统分配了8B内存,这样就浪费了2B的内存,这就是内存的内碎片

当多次使用malloc()后,可能会出现如下情况:即使系统中的累积空闲内存远远大于1MB,但系统仍然没法分配要申请的连续的1MB空间,因为经过多次malloc()后,这1MB的内存被分得七零八散的,这些零散的但又不能供用户使用的内存块就称为内存外碎片

内部碎片就是已经被分配出去(能明确指出属于哪个线程)却不能被利用的内存空间。
外部碎片指的是还没有被分配出去(不属于任何线程),但由于太小了,无法分配给申请内存空间的新线程的内存空闲区域。

内碎片和外碎片是内存管理的一对矛盾,减少外碎片就可能增加内碎片,除非增加很多限制条件,同时外碎片没法完全避免的,只是多少问题。

伙伴系统就是比较经典的减少外碎片的内存管理算法,但也只能将外碎片降低到最大1/2总内存大小,但是该算法会产生很大的内碎片,因此伙伴系统只能在特定场合和特定应用中使用。

主流内存管理机制

对于一些应用简单、任务数目事先确定的嵌入式系统或强实时系统,为了减少内存分配在时间上可能带来的不确定性,可采用静态内存分配方式。
静态内存分配方式在系统启动时,为系统中所有任务都分配了所需内存空间,系统运行过程中不会有新的内存请求,因此操作系统不需要专门的内存管理操作。
这样系统使用内存的效率比较低,只适合于应用简单的、任务数目事先确定的嵌入式系统或强实时系统。
另一方面,大多数系统都使用动态内存管理机制,而当前主流的动态内存管理机制又分为固定大小存储管理和可变大小存储管理机制。

固定大小存储管理
固定大小存储管理方式中,内存是由一段连续的内存构成的,这段内存被分为多个大小一样的固定块,这种管理方式可以很好地解决外部碎片,因为每次分配都是固定大小的内存,只要有空闲内存,肯定可以分配某一固定大小的空间。
但是这种管理方式,无法解决内部碎片,因为如果开发人员只想要20B的内存,也会分配256B,因此这种分配方式往往只是用在特定场合,如分配特定大小的数据结构,且只分配这种数据结构,这样就没有内部碎片了。

可变大小存储管理

  1. 任意大小分配的存储管理。即用户需要多少,就分配多少。这种方式主要是为了解决内碎片,因为编程时总不大可能只是完全分配某一种数据结构,有时可能要分配几字节来存储字符等。需求带动发明,这就产生了按任意大小分配的存储管理机制,该方式实现起来比较简单,就是在整个受管理的内存中,找到一块大于用户需求的内存块,然后一分为二,一块是用户申请的内存块大小,剩下的一块是空闲的,用于以后的分配。
    但是用户申请内存、释放内存的时间是随机的,而每一次的申请和释放都有可能产生新的空闲内存块,之后系统可能会将已有的空闲内存块回收、合并成新的空闲块。
    因此,系统中的空闲内存块的数量、地址、大小是时刻变化的,这就必须采取一种方式来组织这些空闲块,以寻找空闲块和合并空闲块,实现时往往采用链表方式。
    正因为是链表,且链表上的空闲内存块的大小是不定的,从而内存分配和回收的时间无法确定。
  2. 带固定大小特性的可变大小的存储管理。
    这种内存管理同时具备固定大小和可变大小的特性,固定大小,是指大小只能均为2的k次幂(k为某个正整数),同时他可以分配2i大小的内存(m>i>k),这种存储管理机制的典型是伙伴系统。

总结
固定大小内存管理,没有外部碎片,若使用不当,内碎片很大,分配回收速度快,分配时间确定性好。
任意大小存储管理,很少内部碎片,外碎片比较严重,分配回收速度慢,分配时间确定性差。
带固定大小特性的可变大小的存储管理是上面两种方式的结合体,各种性能处于中间位置。

嵌入式系统对内存管理的特殊要求

相对一般系统的内存管理机制,嵌入式系统中对动态内存分配的要求更加高,要考虑的问题也更多,如互斥访问,核间私有Cache的问题。

  1. 内存能快速申请和释放,即快速性。嵌入式系统的实时性保证要求内存分配过程要尽可能地块,这要求算法要简单,分配和释放复杂度为O(1)。
  2. 内存应该各尽其用,即高效性。内存分配要尽可能地少浪费,不可能为了保证满足所有用户的内存分配请求而将内存配置得无限大。

aCoral的内存管理机制

aCoral的内存管理机制在伙伴系统基础上,采用了位图方式提高了内存分配和回收速度的确定性,更能够满足系统实时性的需求。

首先,aCoral的内存管理分为两级,上一级采用改进的伙伴系统,负责确定要分配的内存大小。下一级根据上一级确定的大小进行具体物理内存分配。
因为第一级内存管理总会分配2N大小的内存,这就解决了系统外部碎片和内部碎片的问题。
第二级采用了固定块和可变大小两种累成管理方式,除内核外,应用程序一般直接使用第一级的伙伴系统。

你可能感兴趣的:(嵌入式实时操作系统的设计与开发,嵌入式实时操作系统的设计与开发,嵌入式实时操作系统,学习)