7、内核态地址空间
- 直接映射区:线性空间中从 3G 开始最大 896M 的区间,为直接内存映射区
- 动态内存映射区:该区域由内核函数 vmalloc 来分配
- 永久内存映射区:该区域可访问高端内存
- 固定映射区:该区域和 4G 的顶端只有 4k 的隔离带,其每个地址项都服务于特定的用途,如: ACPI_BASE 等
8、进程内存空间
- 用户进程通常情况只能访问用户空间的虚拟地址,不能访问内核空间虚拟地址
- 内核空间是由内核负责映射,不会跟着进程变化;内核空间地址有自己对应的页表,用户进程各自有不同额页表
内存管理算法——对讨厌自己管理内存的人来说是天赐的礼物
1、内存碎片
1) 基本原理
- 产生原因:内存分配较小,并且分配的这些小的内存生存周期又较长,反复申请后将产生内存碎片的出现
- 优点:提高分配速度,便于内存管理,防止内存泄露
- 缺点:大量的内存碎片会使系统缓慢,内存使用率低,浪费大
2) 如何避免内存碎片
- 少用动态内存分配的函数(尽量使用栈空间)
- 分配内存和释放的内存尽量在同一个函数中
- 尽量一次性申请较大的内存,而不要反复申请小内存
- 尽可能申请大块的 2 的指数幂大小的内存空间
- 外部碎片避免——伙伴系统算法
- 内部碎片避免——slab 算法
- 自己进行内存管理工作,设计内存池
2、伙伴系统算法——组织结构
1) 概念
- 为内核提供了一种用于分配一组连续的页而建立的一种高效的分配策略,并有效的解决了外碎片问题
- 分配的内存区是以页框为基本单位的
2) 外部碎片
- 外部碎片指的是还没有被分配出去(不属于任何进程),但由于太小了无法分配给申请内存空间的新进程的内存空闲区域3) 组织结构
- 把所有的空闲页分组为 11 个块链表,每个块链表分别包含大小为 1,2,4,8,16,32,64,128,256,512 和 1024 个连续页框的页块。最大可以申请 1024 个连续页,对应 4MB 大小的连续内存
3、伙伴系统算法——申请和回收
1) 申请算法
- 申请 2^i 个页块存储空间,如果 2^i 对应的块链表有空闲页块,则分配给应用
- 如果没有空闲页块,则查找 2^(i 1) 对应的块链表是否有空闲页块,如果有,则分配 2^i 块链表节点给应用,另外 2^i 块链表节点插入到 2^i 对应的块链表中
- 如果 2^(i 1) 块链表中没有空闲页块,则重复步骤 2,直到找到有空闲页块的块链表
- 如果仍然没有,则返回内存分配失败
2) 回收算法
- 释放 2^i 个页块存储空间,查找 2^i 个页块对应的块链表,是否有与其物理地址是连续的页块,如果没有,则无需合并
- 如果有,则合并成 2^(i 1)的页块,以此类推,继续查找下一级块链接,直到不能合并为止