内存管理是Linux内核的重要功能之一,负责管理物理内存和虚拟内存,以及它们之间的映射关系,以及高效地分配、管理和回收系统内存资源。
1.1 物理内存管理与虚拟内存
物理内存是计算机实际存在的内存,也称为实际内存或主存储器。它是由硬件直接管理和使用的,用于存储程序和数据。物理内存是由内存模块组成,每个内存模块由许多页框组成,每个页框是一个固定大小的内存块,通常为 4KB。
虚拟内存是操作系统提供给应用程序的一种抽象,它允许每个进程拥有自己的地址空间,不需要关心实际物理内存的细节。虚拟内存通常大于实际的物理内存,因为它包括了硬盘上的交换空间。
1.2 内存分区(Memory Zones)
由于硬件和体系结构的限制,Linux将物理内存分为几个区域或“区”。这样做主要是为了解决物理内存的不同部分可能会有不同特性的问题。常见的内存分区包括:
- ZONE_DMA:用于那些只能进行直接内存访问(DMA)的设备。
- ZONE_NORMAL:普通的可直接映射的内存区域。
- ZONE_HIGHMEM:不能直接映射到内核空间的高地址内存,主要用于32位系统。
1.3 分页
Linux内核通过“页”来管理物理内存,页是物理内存管理的基本单位。常见的页大小为4KB,也支持大页(如2MB、1GB)。
1.3.1 基本概念。
页帧(也称页框)(Page Frame)
页帧指的是物理内存中的一个固定大小的内存块。现代操作系统通常将物理内存划分成固定大小的页帧(通常是 4 KB 或更大)。每个页帧都有一个唯一的物理地址。
页表(Page Table)
用于将虚拟页面映射到物理页帧的表。
页面(Pages)
页面是虚拟内存管理中的概念,指的是虚拟内存空间中的一个固定大小的内存块。操作系统将虚拟地址空间划分成大小相同的页面,并通过页表将这些页面映射到物理内存中的页帧。
内存管理单元(MMU)
硬件中的 MMU 负责将虚拟地址转换为物理地址,并执行访问控制。
1.3.2 页面与页帧的映射关系(物理内存与虚拟内存之间的映射)
虚拟内存中的页面通过页表映射到物理内存中的页帧。这种映射使得操作系统能够灵活管理内存,将虚拟地址转换为物理地址。
1.3.3 通过分页进行内存保护
每个页面可以被赋予不同的权限(如读、写、执行),这有助于操作系统保护内存不被未授权的访问或修改。
1.3.4 页面置换
页面置换是指在物理内存不足时,将不活跃或低优先级的页面移出物理内存,将其存放在交换空间(Swap Space)中,以便腾出空间给需要的页面。当这些页面再次被访问时,它们会被重新加载到物理内存。
1.3.4.1 页面置换算法
- LRU(Least Recently Used):选择最近最少使用的页面进行置换。
- FIFO(First In, First Out):选择最先进入内存的页面进行置换。
- LFU(Least Frequently Used):选择使用频率最低的页面进行置换。
- Clock(时钟算法):一种改进的 LRU 算法,用一个时钟指针循环检查页面的使用情况。
1.3.4.2 交换(Swap)
交换空间
交换空间可以是交换分区或交换文件,用于存储从物理内存中移出的页面。交换空间为系统提供额外的虚拟内存,缓解物理内存不足的问题。
交换机制
当内存紧张时,内核将不常用的页面写入交换空间。
当需要访问这些页面时,内核会从交换空间将页面读回内存。
1.3.4.3 页错误(Page Fault)
当进程访问一个不在物理内存中的页面时,会触发页错误。内核会处理页错误,将所需页面从交换空间加载回内存。
1.3.4.4 页面置换的过程
1.检测页面访问:当一个页面被访问而它不在物理内存中时,产生页错误。
2.选择页面置换:内核使用页面置换算法选择一个页面,将其写入交换空间(如果已改)。
3.加载新页面:将需要的页面从交换空间或文件系统加载到物理内存中。
4.更新页表:更新页表以反映新的页面映射。
1.4 伙伴系统(Buddy System)
伙伴系统是一种内存分配技术,用于管理物理内存中的空闲页。它通过将空闲页组织成不同大小的块(通常是2的幂次大小)来工作。当系统需要分配内存时,伙伴系统可以快速找到合适大小的空闲块,从而提高了内存分配的效率。
1.4.1 内存块划分
内存被划分成大小为 2k字节的块,其中 k 是非负整数。最小块大小通常为一个页面(例如 4KB)。其中每个块称为一个“伙伴块”。
1.4.2 伙伴关系:
每个块都有一个“伙伴块”,两个伙伴块可以合并成一个更大的块。两个块是伙伴的条件是它们的起始地址满足某种对齐要求。例如,对于大小为 2k的块,块 A 和块 B 是伙伴,当且仅当块 A 的起始地址与块 B 的起始地址差为 2k并且块 A 的起始地址是2k+1的整数倍。
1.4.3 内存分配:
当需要分配大小为2k的内存时,系统会在大小为 2k 的空闲列表中查找。如果找不到合适大小的空闲块,系统会从更大的块中分裂出一个大小为 2k 的块。分裂后的块会被放入相应的空闲列表。
1.4.4 内存释放:
当释放一个大小为 2k 的块时,系统会检查其伙伴块是否也是空闲的。如果是,则合并这两个块,形成一个更大的块,并将其放入相应的空闲列表中。这个过程会递归进行,直到无法再进行合并为止。
1.5 内存管理命令和工具
- vmstat:显示虚拟内存统计信息,包括内存使用、分页和交换活动。
- top/htop:实时监控系统资源使用情况,包括内存和交换使用。
- free:显示系统内存的总量、已用、空闲和交换使用情况。
- /proc/meminfo:提供详细的内存使用信息,通过读取该文件获取内存状态。