| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> Linux内存管理二(虚拟内存与物理内存管理) -> 正文阅读 |
|
[系统运维]Linux内存管理二(虚拟内存与物理内存管理) |
创作人QQ:851301776,邮箱:lfr890207@163.com 个人座右铭: 前言、内存管理子系统图一、伙伴分配器????????内核初始化完毕后,使用页分配器管理物理页,当前使用的页分配器就是伙伴分配器,伙伴分配器的特点就是管理算法简单高效 1.基本伙伴分配器??????? 连续的物理页成为页块(page block),阶(order)是页的数量单位,2的n次方个连接物理页称为n阶页块,满足以下条件的两个n阶页块称为伙伴(buddy)。 ??????? (1)两个页块是相邻的,即物理地址是连续的。 ??????? (2)页块的第一页的物理面页号必须是2的n次方的整数倍 ??????? (3)如果合并(n+1)阶页块,第一页的物理页号必须是2的括号(n+1)次方的整数倍 ??????? 伙伴分配器和释放物理页的数量单位也为阶(order)。 ??????? 分配n阶页块过程: ??????? 以单页为说明,0号页和1号页是伙伴,2号页和3号页是伙伴。1号页和2号页不是伙伴? ??????? 因为1号页和2号页合并组成1阶页块,第一页的物理号不是2的整数倍。 2.分区伙伴分配器????????内存区域的结构体成员free_area用来维护空闲页块,数组下标对应页块的除数。结构体free_area的成员free_list是空闲页块的链表,nr_free是空闲页块的数量。内存区域的结构体成员managed_pages是伙伴分配器管理的物理页的数量。 ??????? 内核在基本伙伴分配器基础上进一步扩展: ??????? (1)支持内存节点和区域,称为分区的伙伴分配器 ??????? (2)为预防内存碎片,把物理页根据可移动性分组 ??????? (3)针对分配页做性能优化,为减少处理器之间的锁竞争,在内存区域增加1个处理器页集合。 2.1内存区域数据结构分析? ? ?2.2区域水线数据结构分析??????? 首选的内存区域在什么情况下从备用区域借用物理页?此问题从区域水线讲解深入理解,每个内存区域有3个水线。 ??????? (1)高水线(HIGH):如果内存区域的空闲页数大于高水线,说明该内存区域的内存充足 ??????? (2)低水线(LOW):如果内存区域的空闲页数小于低水线,说明该内存区域的内存轻微不足 ??????? (3)最低水线(MIN):如果内存区域空闲页数小于最低水线,说明该内存区域的内存严重不足 ???????? enum zone_watermarks { ????????WMARK_MIN, ????????WMARK_LOW, ????????WMARK_HIGH, ????????NR_WMARK }; struct zone { ????????/* Read-mostly fields */ ????????/* zone watermarks, access with *_wmark_pages(zone) macros */ ????????unsigned long watermark[NR_WMARK]; ????????...... ????????atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS]; } cacheline_internodealigned_in_smp ?2.3计算水线的两个参数?2.4计算水线的方法?二、slab、slub、slob块分配器1.基本概念????????Buddy提供以page为单位的内存分配接口,这对内核来说颗粒度还太大,所以需要一种新的机制,将page拆分为更小的单位来管理。 ????????Linux中支持的主要有:slab、slub、slob。其中slob分配器的总代码量比较少,但分配速度不是最高效的,所以不是为大型系统设计,适合内存紧张的嵌入式系统。 2.slab块分配器原理????? slab分配器的作用不仅仅是分配小块内存,更重要的作用是针对经常分配和释放的对象充当缓存。slab分配器的核心思路是:为每种对象类型创建一个内存缓存,每个内存缓存由多个大块组成,一个大块是由一个或多个连续的物理页,每个大块包含多个对象。slab采用面向对象的思想,基于对象类型管理内存,每种对象被划分为一类,比如进程描述符task_struct是一个类,每个进程描述符实例是一个对象。如下图所示为内存缓存的组成结构: slab分配器在某些情况下表现不太优先,所以Linux内核提供两个改进的块分配器: (1)在配备大量物理内存的大型计算机上,slab分配器的管理数据结构的内存开销比较大,所以设计了slub分配器; (2)在小内存的嵌入式设备上,slab分配器的代码过多、相当复杂,所以设计一个精简slob分配器。目前slub分配器已成为默认的块分配器。 ?3.系统接口通用的内存缓存的编程接口如下: (1)分配内存kmalloc:kmalloc(size_t size,gfp_t flags) (2)重新分配内存krealloc:krealloc(const void *p,size_t new_size,gpf_t flags) (3)释放内存kfree;kfree(const void *objp) 创建专用的内存缓存编程接口如下: (1)创建内存缓存kmem_cache_create (2)指定内存缓存分配kmem_cache_alloc (3)释放对象kmem_cache_free (4)销毁内存缓存keme_cache_destroy ?4.内核缓存数据结构?内核缓冲数据结构如下图: ?5.计算slab长度及着色(1)计算slab????????函数calculate_slab_order负责计算slab长度,从0阶到kmalloc()函数支持最大除数KMALLOC_MAX_ORDER 。 ???????? (2)着色????? slab是一个或多个连续的物理页,起始地址总是页长度的整数倍,不同slab中相同偏移的位置在处理器一级缓存中的索引相同。如果slab的剩余部分的长度超过一级缓存行的长度,剩余部分对应的一级缓存行没有被利用;如果对象的填充字节的长度超过一级缓存行的长度,填充字节对应的一级缓存行没有被利用。这两种情况导致处理器的某些缓存行被过度使用,另一些缓存行很少使用。 6.每处理器的数据缓存????????内存缓存为每个处理器创建一个数组缓存(结构体array_cahce)。释放对象时,把对象存放到当前处理器对应的数组缓存中;分配对象的时候,先从当前处理器的数组缓存分配对象,采用后进先出(Last In First Out,LIFO)的原则,这种做可以提高性能。 ? ? 7.slab分配器支持UNMA体系结构 内存缓存针对每个内存节点创建一个kmem_cache_node实例 ? ?8.回收内存??????? 对于所有对象空闲的slab,没有立即释放,而是放在空闲slab链表中。只有内存节点上空闲对象的数量超过限制,才开始回收空闲slab,直到空闲对象的数量小于或等于限制。结构体kmem_cache_node的成员slabs_free是空闲slab链表的头节点,成员free_objects是空闲对象的数量,成员free_limit是空闲对象的数量限制 ?节点x的空闲对象的数量限制=(1+节点的处理器数量)*keme_cache.batchcount+kmem_cache.num 三、不连续页分配器????????当设备长时间运行后,内存碎片化,很难找到连续的物理页。在这种情况下,如果需要分配长度超过一页的内存块,可以使用不连续页分配器,分配虚拟地址连续但是物理地址不连续的内存块。在32位系统中不连分配器还有一个好处:优先从高端内存区域分配页,保留稀缺的低端内存区域。 1.系统编程接口(1)不连续页分配器提供的编程接口????????vmalloc:分配不连续的物理页并且把物理页映射到连续的虚拟地址空间 ????????vfree:释放vmalloc分配的物理页和虚拟地址空间 ????????vmap:把已经分配的不连续物理页映射到连续的虚拟地址空间 ????????vunmap:释放使用vmap分配的虚拟地址空间 (2)内核提供函数接口????????kvmalloc:首先尝试使用kmalloc分配内存块,如果失败,那么使用vmalloc函数分配不连续的物理页 ????????kvfree:如果内存块是使用vmalloc分配的,那么使用vfree释放,否则使用kfree释放 2.数据额结构不连续页分配器的数据结构关系如下: ? ?????????每个虚拟内存区域对应一个vmap_area实例; ????????每个vmap_area实例关联一个vm_struct实例; 3.技术原理????????vmalloc虚拟地址空间的范围是(VMALLOC_START,VMALLOC_END),每种处理器架构都需要定义这两个宏。 如ARM64架构定义宏如下:
vmalloc函数执行过程:
(1)分配虚拟内存区域
(2)分配物理页
(3)在内核的页表中把虚拟页映射到物理页
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/16 3:32:31- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |