当前位置:首页 > 嵌入式 > 嵌入式软件
[导读]本文主要介绍了linux内核的内存管理机制。什么是内存管理机制?内存管理主要负责完成当进程请求内存时给进程分配可用的内存,当进程释放内存时,回收相应的内存,同时负责跟踪系统中相应内存的使用状态。  

本文主要介绍了linux内核的内存管理机制。什么是内存管理机制?内存管理主要负责完成当进程请求内存时给进程分配可用的内存,当进程释放内存时,回收相应的内存,同时负责跟踪系统中相应内存的使用状态。  

Linux采用页式内存管理,页是物理内存管理的基本单位。但严格来说Linux采用的是段页式内存管理,既分段也分页。内存映射的时候,先确定对应的段,确定段基地址,段内分页,再找到对应的页表项,确定页基地址,再由逻辑地址的低位确定的页偏移量就能找到最终的物理地址。但Linux中的所有段地址都是0,即所有的段是相同的,之所以有段的概念是因为Linux为了符合硬件体系。所以Linux实际采用的是页式内存管理,但段的概念在内核中确实存在。 

1、物理内存的管理 

 Linux中首先将内存分为若干个节点,每个节点下面又可分为1~3个区,每个区下面会有若干个页。  

(1)节点 

内存节点主要是依据CPU访问代价不同而划分的。一个CPU对应一个节点。内核数组node_data[]形式组织节点,存储的为struct page_data_t指针来描述内存分区。 

(2)区

内核以struct_zone来描述内存分区。内核将所有的物理页分为3个区:ZONE_DMA、ZONE_NORMAL、ZONE_HIGHMEM。  ZONE_DMA区中包含的页可以用来进行DMA操作,即直接内存访问操作,通常为物理内存的起始16M。ZONE_NORMAL区包含的页是可以进行正常的内存映射的页物理内存为16~896M。ZONE_HIGHMEM区称为“高端内存”,该区所包含的页不可以进行永久映射,即不可以永久映射到内核地址,物理内存896M以后的。 

高端内存的边界为896M的原因:32为Linux系统中虚拟内存空间为0-4G,3G-4G为内核态。为了应对内核映射超过1G,Linux采取的策略:内核地址空间的896M采用固定映射,映射方法:虚拟地址-3G=物理地址,只能映射896M,即3G~3G+896M,剩余的128M(3G+896M~4G)采用动态映射。  Linux下以struct zone结构体来表示一个区,在该结构体中变量struct page *zone_mem_map用来管理该区下的内存映射表。 

(3)页 

每一个物理页框都使用一个数据结构struct page来描述,该结构体中的lru变量构建用于LRU页面置换的链表。在页框空闲情况下,该成员变量用于构建伙伴算法、链表同等大小的空闲内存块。大多数32bit的操作系统的页大小为4KB。 

2、伙伴算法 

Linux采用的是伙伴(Buddy)算法对物理内存进行管理。伙伴机制是操作系统的一种动态存储管理算法,该算法通过不断平分较大的空闲内存块来获得较小的空闲内存块,直到获得所需的内存块。当内存释放时,该算法尽可能的合并空闲块。该算法要求内存块的分配和合并都是以2的幂次方为单位。  在“区”内存结构体struct zone中有一struct free_area类型的数组free_area[],数组最大为12个元素。数组的下标k对应着固定大小2^k个页框空闲内存区域的双向链表头。当需要空闲块为4(即2^2)个页框时则查找free_area[2],如果没有合适的,则查找free_area[3],直到找到合适的。

3、slab分配器 

Linux中引入slab是为了减少对伙伴算法的调用,采用slab分配器来减少频繁分配和释放内存数据结构的开销,同时减少了碎片的产生。slab分配机制是基于伙伴算法之上实现。  slab是基于一组对象缓存,把不同对象划分为caches(物理内存),每个cache保存一种类型的对象,每个cache由一个或者多个slab组成,每个slab包含一个或者多个page组成。 

每个slab处于3中状态之一,即full、partial和empty(分别是满、部分满、空),其中满状态的slab没有任何可分配的空闲对象。当请求空闲对象时则从部分满和空的slab中分配。  

Linux内核中的cache以结构体kmem_cache_s来表示,结构体中变量lists中存储的为三个链表分别对应于slab的三种状态。  总结来说,当为一对象申请内存时,首先查找到该对象的cache,然后查找cache中的slab列表,分配空闲内存。当释放该对象内存时,则返回给该对象对应的slab。这样伙伴算法就不需要频繁的进行分配和合并操作。 

4、虚拟内存 

(1)逻辑地址->线性地址->物理地址的转换过程 

逻辑地址即程序指令的地址,线性地址指页式转换前的地址(虚拟地址),物理地址则是物理内存中的地址。 

一个逻辑地址由两部份组成,段标识符: 段内偏移量。段基址确定它所在的段居于整个存储空间的位置,偏移量确定它在段内的位置。Linux中由于段基址都是0,所以逻辑地址和线性地址相同。线性地址再通过MMU进行转换到物理地址,这个过程下面重点讲下。  Linux也是内存管理使用三级表结构:页目录、页中间目录、页表。一个活动任务都有一个页目录,大小一般为一页,页目录必须在内存中。页中间目录可以跨越多个页。页表同样可以跨越多个页,对应具体的页框。具体过程如下图:

(2)页面置换算法 

Linux中页结构体的组织方式为双向循环链表。Linux中页面置换算法基于时钟算法机制实现,页结构体page中有一变量count专门用来计算页面被引用的次数。每当页面被访问一次时,count加1。在Linux后台,Linux周期性地扫描全局页池,并且当它在内存中的所有页间循环时,将扫描的每一页的count减1。age越大则使用频率越高。最终内核通过最近未使用(LRU)算法进行页面置换。

5、高速缓存 

Linux使用了一系列的高速缓存相关的内存管理技术来提高性能。此处的高速缓存并非

是物理缓存,而是软件方法。Linux中主要包括以下几个缓存:  

(1)Buffer Cache,包括了用于块设备驱动程序的数据缓冲区。这些缓存区固定(一般512B),包括从块设备要读取的数据和要写入块设备的数据。操作时先查看缓冲区。  

(2)Page Cache,用来加快对磁盘上映像和数据的访问。用来缓存文件的逻辑内容,一次缓存一页。  

(3)Swap Cache,只有改动过的(或脏)页才存在交换文件中,只要交换文件没有再次修改,下次这些页需要交换出时就不需要再写到交换文件中。  

 

(4)Hardware Cache,常见方法是在处理器中PTE的高速缓存。这种情下处理器不需要直接读取页表,需要时把页表放在缓存区中。CPU有转换表缓冲区(TLB),来快速查找置换页表。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭